Co oznacza znak dolara, po którym następuje znak at-sign ( @
) w skrypcie powłoki?
Na przykład:
umbrella_corp_options $@
Co oznacza znak dolara, po którym następuje znak at-sign ( @
) w skrypcie powłoki?
Na przykład:
umbrella_corp_options $@
Odpowiedzi:
$@
to wszystkie parametry przekazane do skryptu.
Na przykład, jeśli zadzwonisz ./someScript.sh foo bar
wtedy $@
będzie równa foo bar
.
Jeśli zrobisz:
./someScript.sh foo bar
a następnie wewnątrz someScript.sh
odniesienia:
umbrella_corp_options "$@"
zostanie to przekazane umbrella_corp_options
z każdym parametrem ujętym w podwójne cudzysłowy, umożliwiając pobranie parametrów z pustą spacją od osoby dzwoniącej i przekazanie ich dalej.
someScript.sh foo bar "boo far"
?
$@
czy niekoniecznie pochodzą z paramaters przekazanych do skryptu ... np; set a b "x y"; printf '(%s)' "$@"
wyniki(a)(b)(x y)
$@
i$*
$@
jest prawie taki sam jak $*
, oba oznaczają „wszystkie argumenty wiersza poleceń”. Często są one używane do przekazywania wszystkich argumentów do innego programu (tworząc w ten sposób opakowanie tego innego programu).
Różnica między dwiema składniami pojawia się, gdy masz argument ze spacjami (np.) I wstawisz $@
podwójne cudzysłowy:
wrappedProgram "$@"
# ^^^ this is correct and will hand over all arguments in the way
# we received them, i. e. as several arguments, each of them
# containing all the spaces and other uglinesses they have.
wrappedProgram "$*"
# ^^^ this will hand over exactly one argument, containing all
# original arguments, separated by single spaces.
wrappedProgram $*
# ^^^ this will join all arguments by single spaces as well and
# will then split the string as the shell does on the command
# line, thus it will split an argument containing spaces into
# several arguments.
Przykład: dzwonienie
wrapper "one two three" four five "six seven"
spowoduje:
"$@": wrappedProgram "one two three" four five "six seven"
"$*": wrappedProgram "one two three four five six seven"
^^^^ These spaces are part of the first
argument and are not changed.
$*: wrappedProgram one two three four five six seven
wrappedProgram "$*"
-> separated by single spaces.
ale w drugim przykładzie nie są one oddzielone pojedynczymi spacjami.
Oto argumenty wiersza poleceń, w których:
$@
= przechowuje wszystkie argumenty na liście ciągów
$*
= przechowuje wszystkie argumenty jako pojedynczy ciąg
$#
= przechowuje liczbę argumentów
Użycie czystych $@
środków w większości przypadków „rani programistę tak mocno, jak to możliwe”, ponieważ w większości przypadków prowadzi to do problemów z separacją słów oraz spacjami i innymi znakami w argumentach.
W (przypuszczalnie) 99% wszystkich przypadków wymagane jest zawarcie go w "
: "$@"
to, co można wykorzystać do rzetelnego iterowania argumentów.
for a in "$@"; do something_with "$a"; done
for a in start_token "$@" end_token; do something_with "$a"; done
:-)
@
Rozwija się do parametrów pozycyjnych, zaczynając od jednego. Kiedy rozwinięcie występuje w podwójnych cudzysłowach, każdy parametr rozwija się do osobnego słowa. Oznacza to, że „$ @” jest równoważne z „$ 1” „$ 2” .... Jeśli podwójne wyrażenie występuje w jednym słowie, rozszerzenie pierwszego parametru jest łączone z początkową częścią oryginalnego słowa, a rozwinięcie ostatniego parametru jest połączone z ostatnią częścią oryginalnego słowa. Gdy nie ma parametrów pozycyjnych, „$ @” i $ @ rozwijają się do zera (tzn. Są usuwane).
Krótko mówiąc, $@
rozwija się do argumentów pozycyjnych przekazywanych przez program wywołujący do funkcji lub skryptu . Jego znaczenie zależy od kontekstu : wewnątrz funkcji rozwija się do argumentów przekazywanych do takiej funkcji. Jeśli zostanie użyty w skrypcie (nie wchodzi w zakres funkcji), rozwija się do argumentów przekazywanych do takiego skryptu.
$ cat my-sh
#! /bin/sh
echo "$@"
$ ./my-sh "Hi!"
Hi!
$ put () ( echo "$@" )
$ put "Hi!"
Hi!
Kolejnym tematem, który ma ogromne znaczenie dla zrozumienia, jak $@
zachowuje się w powłoce, jest podział słów . Powłoka dzieli tokeny na podstawie zawartości IFS
zmiennej. Jego wartością domyślną jest \t\n
; tj. biała spacja, tabulator i nowa linia.
Rozwijanie "$@"
daje nieskazitelną kopię przekazywanych argumentów. Jednak rozszerzenie $@
nie zawsze. Mówiąc dokładniej, jeśli argumenty zawierają znaki z IFS
, zostaną podzielone.
Przez większość czasu, co chcesz używać to "$@"
nie $@
.