Gdzie indziej widziałem funkcję cd, jak poniżej:
cd()
{
builtin cd "$@"
}
dlaczego zaleca się używać $@
zamiast $1
?
Utworzyłem katalog testowy „r st” i wywołałem skrypt zawierający tę funkcję i działał on w obie strony
$ . cdtest.sh "r st"
ale $ . cdtest.sh r st
zawiodło, czy użyłem "$@"
czy"$1"
cd "$*"
również nie będzie działać poprawnie z więcej niż 1 arg.Odpowiedzi:
Ponieważ, zgodnie z
bash(1)
,cd
bierze argumentydlatego katalog może nie być w rzeczywistości,
$1
ponieważ może to być opcja taka jak-L
lub inna flaga.Jak źle to jest?
Wszystko może pójść nie tak, jeśli nie skończysz w miejscu, w którym spodziewasz się
cd "$1"
…źródło
Użycie
"$@"
spowoduje przekazanie wszystkich argumentów do miejsca,cd
gdzie$1
zostanie przekazany tylko pierwszy argument.W twoich przykładach
zawsze działa, gdy przekazujesz tylko jeden argument, ale jeśli miałbyś również przekazać flagę, taką jak
Wtedy tylko
"$@"
wykona się poprawnie, gdzie"$1"
rozwinie się docd -L
utraty katalogu całkowicie.jednak
Nie powiedzie się w obu przypadkach, jak przechodzą dwa parametry na CD,
r
ist
który nie jest prawidłowym sposobem wykonać cd. Parametry są oddzielone spacjami, które muszą być cytowane (jak w twoim pierwszym przykładzie) lub escaped (r\ st
), aby traktować je jako jeden argument.Jednak w przypadku cd przekazywanie flag jest bardzo rzadkie i nie można przekazywać wielu katalogów, więc nie zobaczysz różnicy w korzystaniu z jednego
"$1"
lub"$@"
drugiego z nich w świecie rzeczywistym . Ale dla innych poleceń, będzie zauważyć różnicę więc najlepiej jest, aby zawsze używać"$@"
, gdy chcemy utworzyć funkcję otoki lub skryptu takiego.źródło
Jest również przypadek, gdy nie ma argumentów:
cd
bez żadnych argumentów zmiany w katalogu domowym. Bez żadnych argumentów"$@"
rozwija się do zera, ale"$1"
rozwija się do pustego łańcucha. Są różne:źródło
cd
jest dobrą rzeczą. Powoduje błąd zamiast przejścia do katalogu domowego. W przypadku niektórych innych poleceń, w szczególnościrsync
pierwszy zerowy argument powoduje nieoczekiwane zachowanie (obejmuje bieżący katalog w źródłach przesyłania).Argumenty do skryptu bash są rozdzielane spacjami. 1 $ to pierwszy argument. W twoich przykładach ...
W przykładzie 1 $ 1 to ciąg „r st” ... w drugim przykładzie $ 1 to ciąg jednego znaku „r” ...
$ @ to wszystkie argumenty.
źródło