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*
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*
Odpowiedzi:
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ść:
Jeśli wtedy wpiszesz, mv *
dzieje się coś, co wydaje się dziwne: test3
jest, 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, echo
dosłownie po prostu powtórzy wszystko, co bash mu przekazał jako argument.cp temp temp*
będzie zachowywać się trochę jak mv
polecenie, 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.*
zamiast ls
. Na przykład for f in *; do
jest 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ć.)
shopt nullglob
jest.
Jak już wspomniano, powłoka rozwija się, *
więc echo
odbieraj 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, ls
ponieważ 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 \*
.
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.
rm
Oczywiście może istnieć plik o nazwie .
-rf
? Próbowałem touch -rf
i touch \-rf
, ale nie jest jej tworzenie.
-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ć)
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