Isso é semelhante à pergunta SO aqui , que é semelhante ao comentário @costas. Você pode usar $#
para obter o número de argumentos e, em seguida, referências indiretas como ${!i}
para acessar uma variável pelo nome. Aqui está um exemplo:
f() {
for((i=1; i<=$#; i++)); do
printf "%d %s\n" "$i" "${!i}"
done
}
f a b c
quais impressões:
1 a
2 b
3 c
Ver agora que você deseja passar os nomes das variáveis como argumentos posicionais, você pode adicionar uma camada extra de referência indireta da seguinte forma:
a=first
b=second
c=third
f() {
for((i=1; i<=$#; i++)); do
var="${!i}"
printf "%d %s\n" "$i" "${!var}"
done
}
f a b c
que imprime
1 first
2 second
3 third
Isso nos permite tratar cada argumento como o nome de uma variável, que armazenamos em var
aqui. Então, acessamos essa variável indiretamente no printf
.
Você só recebe uma camada de indireção de cada vez, o aninhamento não funciona. Então, tentar fazê-lo de uma só vez como ${!${!i}}
não funciona porque o primeiro {
inicia a expansão, com o restante sendo tratado como o valor PARÂMETRO a ser expandido. O primeiro caractere sendo !
tratará o restante como o nome do PARAMETER contendo o nome do parâmetro desejado, mas ${!i}
não é um nome de parâmetro válido, portanto, obtemos um bad substitution
. Então, fazemos isso em duas etapas para evitar esse problema.