Co oznacza $ @ w skrypcie powłoki?


Odpowiedzi:


242

$@to wszystkie parametry przekazane do skryptu.

Na przykład, jeśli zadzwonisz ./someScript.sh foo barwtedy $@będzie równa foo bar.

Jeśli zrobisz:

./someScript.sh foo bar

a następnie wewnątrz someScript.shodniesienia:

umbrella_corp_options "$@"

zostanie to przekazane umbrella_corp_optionsz 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.


1
Co zawiera $ @, gdybym to zrobił someScript.sh foo bar "boo far"?
trusktr


7
$ @ jest wyjątkowy, jeśli jest napisany w podwójnym cudzysłowie. Doprowadzi to do utworzenia listy cytowanych wartości, w twoim przypadku trusktr, z trzema argumentami „foo”, „bar” i „boo far”.
Alfe,

4
Chociaż jest to zwykle ma miejsce, $@czy niekoniecznie pochodzą z paramaters przekazanych do skryptu ... np; set a b "x   y"; printf '(%s)' "$@"wyniki(a)(b)(x   y)
Peter.O

Bardziej podoba mi się odpowiedź Alfe'a, ponieważ podaje on główną różnicę między $@i$*
donleyp

106

$@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

2
Nie są one takie same, a strona podręcznika pokazuje efekty uboczne $ * przy użyciu IFS - co niekoniecznie jest przestrzenią. (Gdyby były takie same, oferowanie obu nie miałoby żadnego innego znaczenia niż zgodność).
jørgensen

6
Nie oni nie są. I tak powiedział dwie linie poniżej: „Różnica między nimi ...” w celu uzyskania krótkich zdań i podnieść czytelność czytelnik ma więcej niż jedno zdanie przed wydaniem wyroku: - /
Alfe

2
Alfe, wstawienie przez Christoffera tego jednego słowa „prawie” zrobiło ogromną różnicę, nie poświęcając żadnej zwięzłości czy czytelności. W rzeczywistości głosowałem za odpowiedzią (w przeciwieństwie do przyjętej) właśnie z powodu tego subtelnego podkreślenia różnicy ... - zanim zdałem sobie sprawę, że było to wbrew twojej woli! ;)
Sz.

Myślę, że to słowo zrobiło ogromną różnicę dla ludzi, którzy wydają werdykt zaraz po przeczytaniu pierwszego zdania ;-) i nigdy nie było wbrew mojej woli. Naprawdę chciałbym pisać także dla tych ludzi.
Alfe

Bardzo niejasne. wrappedProgram "$*"-> separated by single spaces.ale w drugim przykładzie nie są one oddzielone pojedynczymi spacjami.
Felix Dombek

36

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


(Powyższa niedokładność wspomniana przez @iruvar została naprawiona.)
Mateen Ulhaq

13

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

4
Twój wiersz można zapisać jako: dla; zrób coś z „$ a”; gotowe ;-)
Alfe,

1
@Afe, wiem; po prostu zapomniałem. Pomyśl o tym jako for a in start_token "$@" end_token; do something_with "$a"; done:-)
glglgl

9

Z instrukcji:

@

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).


1

Znaczenie.

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!

Podział słów.

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 IFSzmiennej. 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 $@.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.