Kto zajmuje się gwiazdą * w echu *

15

Kto zajmuje się (interpretuje) * w

echo *

Czy echo widzi gwiazdę lub powłokę, które się tym zajmują i zwraca listę nazw plików ...

Co powiesz na

cp temp temp*
faressoft
źródło
14
To się zmienia. Powłoki Unix czy Windows?
user1686
@grawity Unix shells. Przepraszam, że o tym nie wspomniałem.
faressoft
W przypadku Uniksa poniższe odpowiedzi są poprawne. (W systemie Windows jest to wykonywane przez poszczególne programy - choć zwykle automatycznie przez bibliotekę wykonawczą przed main ().)
user1686 14.04.15

Odpowiedzi:

24

bash (lub cokolwiek użyjesz jako powłoki), jest pierwszą rzeczą, która czyta jakiekolwiek dane wejściowe i zaczyna interpretować znaki specjalne, takie jak ?i *. *zostaje rozszerzone do dowolnych dopasowań w CWD , co oznacza, że ​​gwiazdka jest zastąpiona wspomnianymi dopasowaniami.

W większości przypadków jest to dość posunięte naprzód, ale od czasu do czasu może prowadzić do mylących przypadków.

Rozważ następujące. Katalog ma następującą zawartość:

  • test (zwykły plik)
  • test1 (katalog)
  • test2 (katalog)
  • test3 (katalog)

Jeśli wtedy wpiszesz, mv *dzieje się coś, co wydaje się dziwne: test3jest, ale reszty już nie ma. Choć początkowo jest to dziwne, ma sens, gdy zrozumiesz, co właściwie przechodzi bash mv. Z powodu gwiazdki, bash interpretuje mv *jako mv test test1 test2 test3, a kiedy mv pobierze tę listę, przyjmie, że ostatnim argumentem jest miejsce docelowe, w którym wszystkie pliki zostałyby przeniesione.

Jeśli chodzi o wymienione polecenia:

  • echo *może funkcjonować jako biedak ls. Powłoka rozszerzy gwiazdkę na wszystko, co znajduje się w tym katalogu, i jak już jestem pewien, echodosłownie po prostu powtórzy wszystko, co bash mu przekazał jako argument.
  • cp temp temp*będzie zachowywać się trochę jak mvpolecenie, które opisałem powyżej, chyba że istnieje tylko jeden katalog o nazwie temp, w którym to przypadku nazwa źródłowa i docelowa jest taka sama, tzn. nic nie zrobi.
Jarmund
źródło
8
Nie ma nic „słabego” w używaniu *zamiast ls. Na przykład for f in *; dojest bardziej niezawodny niż w for f in $(ls)przypadku, gdy nazwa pliku zawiera spacje lub znak globalny. (Nie powiedzie się jednak, jeśli w CWD nie ma żadnych plików, więc musisz to sprawdzić.)
rici 14.04.15
1
@rici Po to shopt nullglobjest.
CVn
3
Jeśli chodzi o echo *tę sztuczkę , w niektórych przypadkach możesz cię uratować .
CVn
2
Wchodzenie w: pliki poprzedzone znakiem „-” w dowolnych folderach, które uruchamiają niepożądane przełączniki. Usunięcie ich nie jest zabawne, dopóki nie zorientujesz się, że plik rm ./-stupidfile działa.
ɯͽbρɯͽ
1
@ ɯͽbρɯͽ Zauważyłem, kiedy kiedyś musiałem usunąć zawartość katalogu zawierającego pliki o nazwie pliku reprezentującej pozycje w układzie współrzędnych, od -1024x-1024 do 1024x1024. Wtedy po raz pierwszy dowiedziałem się o ucieczce.
Jarmund
5

Jak już wspomniano, powłoka rozwija się, *więc echoodbieraj jako argumenty wszystko, co powłoka znajdzie w bieżącym katalogu. Zauważ jednak, że jeśli rozszerzenie nie prowadzi do niczego, tzn. W takim przypadku, jeśli katalog nie zawiera nie ukrytych plików, *pozostaje niezmieniony i przekazywany tak, jak jest wywoływane polecenie (chyba że w przypadku niektórych powłok, takich jak bash.) echo *nie będzie się wtedy zachowywał jak człowiek biedny, lsponieważ ten pierwszy nic nie wydrukuje, a drugi wydrukuje *.

Podobnie cp /tmp/temp temp*utworzy plik o nazwie temp*w bieżącym katalogu, jeśli nie ma jeszcze co najmniej jednego pliku, którego nazwa zaczyna się od temp.

Wreszcie, jeśli chcesz, *aby przekazywanie odbywało się bez zmian, niezależnie od przypadku, możesz zabezpieczyć go przed rozwinięciem, używając pojedynczych cudzysłowów '*', podwójnych cudzysłowów "*"lub odwrotnego ukośnika \*.

jlliagre
źródło
4

W Bash powłoka radzi sobie z tym. Widzisz to, jeśli nawet spróbujesz *bez echa

W oparciu o niektóre komentarze sugerowałbym, aby podczas uruchamiania * ENTER utworzyć katalog i użyć polecenia touch do utworzenia niektórych plików oraz upewnić się, że żaden z nich, a przynajmniej pierwszy alfabetycznie, nie jest nazwą dowolnego skryptu lub polecenia na ścieżce.

$ *
bash: a: command not found

$ echo *
a a.aa a.ab a.b a.htm a.tx

To ls *trochę banał

W systemie Windows *jest obsługiwany przez polecenie, więc dir *.*nie jest to frazes.

Uwaga: Widząc kilka komentarzy, dodam, istnieje ryzyko uruchomienia *, a następnie ENTER. Jeśli masz plik o nazwie rm, który jest pierwszy na liście katalogów, jest to niebezpieczne, ponieważ wszystko, co po nim zostanie usunięte. Jest to również mniej prawdopodobne, jeśli pierwszy plik na liście katalogów to nazwa skryptu na ścieżce, wówczas zostanie on uruchomiony.

barlop
źródło
4
rmOczywiście może istnieć plik o nazwie .
Volker Siegel,
1
... i kolejny o nazwie -rf
ǝɲǝɲbρɯͽ
1
@ ɯͽbρɯͽ czy możesz mieć plik o nazwie pliku -rf? Próbowałem touch -rfi touch \-rf, ale nie jest jej tworzenie.
barlop
@barlop Skomentowałem powyżej; gui (podobnie jak gedit) dobrze sobie z nimi radzi, ale ponieważ powłoka (przynajmniej bash) przechodzi przez to, wymaga ./ z przodu. Jeśli kiedykolwiek przypadkowo utworzysz taki plik, rm spróbuje podpowiedzieć, ale jeśli nie: mam nadzieję, że trafi on tylko do folderu tymczasowego z jednorazowymi dziećmi.
ɯͽbρɯͽ
@ ɯͽbρɯͽ W ogóle nie rozumiem, co masz na myśli, pytam, jak możesz utworzyć plik o nazwie -rf? (Rozumiem niebezpieczeństwo związane z plikiem o nazwie rm i plikiem o nazwie -rf, a także problemem pisania * i pchania enter w ważnym folderze, nie planuję tego robić)
barlop
-1

Powłoka wykonuje kilka rozszerzeń, zanim argumenty zostaną przekazane do polecenia.

Zobacz także https://www.gnu.org/software/bash/manual/bashref.html#Simple-Command-Expansion

Nie dotyczy bash, patrz http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01

Glenn Jackman
źródło
Technicznie to, co piszesz, jest poprawne, ale bez linków ta odpowiedź tak naprawdę nie robi nic, by odpowiedzieć na pytanie. Rozważ uwzględnienie odpowiednich szczegółów.
CVn
@ MichaelKjörling Zgadzam się z linkiem, ale OP po prostu zapytał, czy powłoka lub sama komenda obsłużyła argumenty. Odpowiedź Glenna po prostu stwierdza, że ​​skorupa je obsługuje, więc jest to akceptowalna odpowiedź na pytanie.
slhck 14.04.15
@slhck Dlatego nie zgłosiłem jako NAA: zostało coś, co rozwiązuje pytanie po usunięciu linków. To nie znaczy, że jest to, moim zdaniem, dobra odpowiedź. (Widzę teraz, że mój wstępny komentarz można interpretować inaczej; przepraszam, ale nadal uważam, że ma on wystarczającą wartość, aby zostawić go tam, gdzie jest).
CVn
@ MichaelKjörling Zgoda. Właśnie zostawiłem komentarz dla tych, którzy oznaczyli go i będą oznaczać jako NAA.
slhck 14.04.15