Como produzir um elemento individual de “$ @”?

4

Eu li que $@ é uma matriz que contém os parâmetros posicionais.

Eu tentei gerar um elemento da matriz $@ :

echo ${@[1]}

Mas bash está me dando este erro:

test.sh: line 1: ${@[1]}: bad substitution
    
por user267935 28.12.2017 / 21:52

2 respostas

15

$@ é um "parâmetro especial" não uma matriz; portanto, você não pode acessá-lo como uma matriz. Você pode acessar os parâmetros diretamente, usando a posição deles: ${1} ... ${n} .

$ set -- a b c d e f g h i j k l m n
$ echo "$#"
14
$ echo "${10}"
j

Como fiquei curioso sobre o comportamento de chaves para os parâmetros 10+, executei um teste contra vários shells:

for shell in ash bash dash fish ksh mksh posh rc sash yash zsh
do
  printf "The %s shell outputs: %s\n" "$shell" "$($shell -c 'set -- a b c d e f g h i j k l m n; echo $10')"
done

Com estes resultados:

The ash shell outputs: j
The bash shell outputs: a0
The dash shell outputs: j
The fish shell outputs:
The ksh shell outputs: a0
The mksh shell outputs: a0
The posh shell outputs: a0
rc: cannot find 'set'
The rc shell outputs:
The sash shell outputs: j
The yash shell outputs: a0
The zsh shell outputs: j

O comportamento de chaves para os parâmetros do shell é explicado na Linguagem de comando do shell seção na expansão do parâmetro Shell:

The parameter name or symbol can be enclosed in braces, which are optional except for positional parameters with more than one digit ...

e o próprio parâmetro $@ special são descritos na mesma página nos Parâmetros especiais seção.

    
por 28.12.2017 / 21:57
5

O $@ é, de fato, uma lista de valores, não uma matriz. A sintaxe de array realmente não funciona. Eles são chamados de "Parâmetros posicionais" e geralmente acessados pela sintaxe $4 (por exemplo).

No bash:

$ set -- a b c d e f g h i j k l m n
$ echo $6
f
$ echo "${11}"
k
$ echo "${@:11:1}"
k

Com um índice:

$ i=11
$ echo "${@:i:1}"
k
$ echo "${!i}"
k

Em conchas mais antigas, não há solução a não ser usar eval (cuidado com os riscos):

$ eval 'var=$'"{$i}"
$ echo "$var"
k

Loops

Os loops são fáceis de gerenciar, basta usar for var; do …; done

$ for pos; do printf '%s:' "$pos"; done; echo
a:b:c:d:e:f:g:h:i:j:k:l:m:n:

O shell disponibiliza automaticamente cada valor na lista para cada loop.

    
por 29.12.2017 / 02:16