$@são todos os parâmetros passados para o script.
Por exemplo, se você ligar ./someScript.sh foo bar, $@será igual a foo bar.
Se você fizer:
./someScript.sh foo bar
e depois dentro de someScript.shreferência:
umbrella_corp_options "$@"
isso será passado para umbrella_corp_optionscada parâmetro individual entre aspas duplas, permitindo pegar parâmetros com espaço em branco do chamador e transmiti-los.
$ @ é especial se estiver escrito entre aspas duplas. Em seguida, resultará em uma lista de valores citados, no seu caso, trusktr, nos três argumentos "foo", "bar" e "vaia longe".
Alfe
4
Embora seja geralmente o caso, $@que não necessariamente vir de paramaters passados para o script ... eg; set a b "x y"; printf '(%s)' "$@"saídas(a)(b)(x y)
Peter.O
I como a resposta de Alfe melhor, porque ele dá a diferença principal entre $@e$*
donleyp
106
$@é quase o mesmo que $*, ambos significando "todos os argumentos da linha de comando". Eles geralmente são usados para simplesmente passar todos os argumentos para outro programa (formando um invólucro em torno desse outro programa).
A diferença entre as duas sintaxes aparece quando você tem um argumento com espaços (por exemplo) e coloca $@aspas duplas:
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.
Exemplo: Chamando
wrapper "one two three" four five "six seven"
vai resultar em:
"$@": 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
Eles não são os mesmos, e a página de manual é clara sobre os efeitos colaterais de $ * usando o IFS - o que não é necessariamente espaço. (Se eles eram os mesmos, não haveria qualquer ponto, diferente de compatibilidade talvez, na oferta de ambos.)
Jorgensen
6
Não, eles não são. E eu disse duas linhas abaixo: "A diferença entre os dois ..." Para obter sentenças curtas e aumentar a legibilidade, o leitor precisa ler mais de uma sentença antes de emitir um veredicto: - /
Alfe
2
Além disso, a inserção de Christoffer dessa única palavra "quase" fez uma enorme diferença, sem sacrificar a concisão ou a legibilidade. Na verdade, eu votei positivamente nesta resposta (em oposição à aceita) exatamente devido à ênfase sutil da diferença ... - antes de perceber que era quase contra a sua vontade! ;)
Sz.
Acho que essa palavra fez muita diferença para as pessoas que deram um veredicto logo após ler a primeira frase ;-) e nunca foi contra a minha vontade. Eu realmente gostaria de escrever também para essas pessoas.
Alfe 02/03
Muito claro. wrappedProgram "$*"-> separated by single spaces.mas no seu segundo exemplo, eles não são separados por espaços únicos.
Felix Dombek #
36
Estes são os argumentos da linha de comando em que:
$@= armazena todos os argumentos em uma lista de cadeias $*= armazena todos os argumentos como uma única cadeia $#= armazena o número de argumentos
(A imprecisão acima mencionado por @iruvar foi fixado.)
Mateen Ulhaq
13
O uso de $@meios puros na maioria dos casos "prejudica o programador o máximo possível", porque na maioria dos casos isso leva a problemas com a separação de palavras e com espaços e outros caracteres nos argumentos.
Em (adivinhado) 99% de todos os casos, é necessário incluí-lo em ": "$@"é o que pode ser usado para iterar de maneira confiável os argumentos.
Expande para os parâmetros posicionais, iniciando em um. Quando a expansão ocorre entre aspas duplas, cada parâmetro se expande para uma palavra separada. Ou seja, "$ @" é equivalente a "$ 1" "$ 2" .... Se a expansão de aspas duplas ocorrer em uma palavra, a expansão do primeiro parâmetro será associada à parte inicial da palavra original e o valor a expansão do último parâmetro é associada à última parte da palavra original. Quando não há parâmetros posicionais, "$ @" e $ @ expandem para nada (ou seja, eles são removidos).
Em resumo, $@expande para os argumentos posicionais passados do chamador para uma função ou um script . Seu significado é dependente do contexto : dentro de uma função, ele se expande para os argumentos passados para essa função. Se usado em um script (não dentro do escopo de uma função), ele se expande para os argumentos passados para esse script.
Agora, outro tópico que é de suma importância ao entender como $@se comporta no shell é a divisão de palavras . O shell divide os tokens com base no conteúdo da IFSvariável. Seu valor padrão é \t\n; ou seja, espaço em branco, guia e nova linha.
A expansão "$@"fornece uma cópia original dos argumentos transmitidos. No entanto, a expansão $@nem sempre será. Mais especificamente, se os argumentos contiverem caracteres de IFS, eles serão divididos.
Na maioria das vezes o que você deseja usar é "$@", não $@.
Respostas:
$@
são todos os parâmetros passados para o script.Por exemplo, se você ligar
./someScript.sh foo bar
,$@
será igual afoo bar
.Se você fizer:
e depois dentro de
someScript.sh
referência:isso será passado para
umbrella_corp_options
cada parâmetro individual entre aspas duplas, permitindo pegar parâmetros com espaço em branco do chamador e transmiti-los.fonte
someScript.sh foo bar "boo far"
?$@
que não necessariamente vir de paramaters passados para o script ... eg;set a b "x y"; printf '(%s)' "$@"
saídas(a)(b)(x y)
$@
e$*
$@
é quase o mesmo que$*
, ambos significando "todos os argumentos da linha de comando". Eles geralmente são usados para simplesmente passar todos os argumentos para outro programa (formando um invólucro em torno desse outro programa).A diferença entre as duas sintaxes aparece quando você tem um argumento com espaços (por exemplo) e coloca
$@
aspas duplas:Exemplo: Chamando
vai resultar em:
fonte
wrappedProgram "$*"
->separated by single spaces.
mas no seu segundo exemplo, eles não são separados por espaços únicos.Estes são os argumentos da linha de comando em que:
$@
= armazena todos os argumentos em uma lista de cadeias$*
= armazena todos os argumentos como uma única cadeia$#
= armazena o número de argumentosfonte
O uso de
$@
meios puros na maioria dos casos "prejudica o programador o máximo possível", porque na maioria dos casos isso leva a problemas com a separação de palavras e com espaços e outros caracteres nos argumentos.Em (adivinhado) 99% de todos os casos, é necessário incluí-lo em
"
:"$@"
é o que pode ser usado para iterar de maneira confiável os argumentos.fonte
for a in start_token "$@" end_token; do something_with "$a"; done
:-)Do manual:
fonte
Significado.
Em resumo,
$@
expande para os argumentos posicionais passados do chamador para uma função ou um script . Seu significado é dependente do contexto : dentro de uma função, ele se expande para os argumentos passados para essa função. Se usado em um script (não dentro do escopo de uma função), ele se expande para os argumentos passados para esse script.Divisão de palavras.
Agora, outro tópico que é de suma importância ao entender como
$@
se comporta no shell é a divisão de palavras . O shell divide os tokens com base no conteúdo daIFS
variável. Seu valor padrão é\t\n
; ou seja, espaço em branco, guia e nova linha.A expansão
"$@"
fornece uma cópia original dos argumentos transmitidos. No entanto, a expansão$@
nem sempre será. Mais especificamente, se os argumentos contiverem caracteres deIFS
, eles serão divididos.Na maioria das vezes o que você deseja usar é
"$@"
, não$@
.fonte