O que significa um cifrão seguido de um sinal de arroba ( @
) em um script de shell?
Por exemplo:
umbrella_corp_options $@
O que significa um cifrão seguido de um sinal de arroba ( @
) em um script de shell?
Por exemplo:
umbrella_corp_options $@
Respostas:
$@
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.sh
referência:
umbrella_corp_options "$@"
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.
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:
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
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 argumentos
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.
for a in "$@"; do something_with "$a"; done
for a in start_token "$@" end_token; do something_with "$a"; done
:-)
@
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.
$ cat my-sh
#! /bin/sh
echo "$@"
$ ./my-sh "Hi!"
Hi!
$ put () ( echo "$@" )
$ put "Hi!"
Hi!
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 IFS
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 de IFS
, eles serão divididos.
Na maioria das vezes o que você deseja usar é "$@"
, não $@
.