Em qualquer shell parecido com o Bourne, é:
for arg
do printf 'Something with "%s"\n' "$arg"
done
Ou seja, for
faz um loop nos parâmetros posicionais ( $1
, $2
...) por padrão (se você não der uma in ...
part).
Note que isso é mais portátil do que:
for arg; do
printf 'Something with "%s"\n' "$arg"
done
Que não era POSIX até a edição de 2016 do padrão nem Bourne (embora funcione na maioria dos outros shells semelhantes a Bourne incluindo bash
mesmo no modo POSIX)
Ou então:
for arg in "$@"; do
printf 'Something with "%s"\n' "$arg"
done
Qual é o POSIX, mas não funciona corretamente no shell Bourne ou no ksh88 quando $IFS
não contém o caractere de espaço, ou com algumas versões do shell Bourne quando não há argumento, ou com alguns shells (incluindo alguns versões de bash
) quando não há argumento e a opção -u
está ativada.
Ou
for arg do
printf 'Something with "%s"\n' "$arg"
done
que é POSIX e Bourne, mas não funciona em shells muito antigas baseadas em cinzas. Eu pessoalmente ignoro isso e uso essa sintaxe como eu acho que é o mais legível e não espere que qualquer código que eu escrevo acabe sendo interpretado por um shell tão arcano.
Mais informações em:
Agora, se você quiser que $i
faça um loop sobre [1..$#]
e acesse os elementos correspondentes, faça o seguinte:
em qualquer shell POSIX:
i=1
for arg do
printf '%s\n' "Arg $i: $arg"
i=$((i + 1))
done
ou:
i=1
while [ "$i" -le "$#" ]; do
eval "arg=\${$i}"
printf '%s\n' "Arg $i: $arg"
i=$((i + 1))
done
Ou com bash
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: ${!i}"
done
${!i}
sendo uma expansão de variável indireta, que é expandida para o conteúdo do parâmetro cujo nome é armazenado na variável i
, semelhante ao sinalizador de expansão do parâmetro zsh
P
:
for ((i = 1; i <= $#; i++ )); do
printf '%s\n' "Arg $i: ${(P)i}"
done