Como usar valores de parâmetros dentro de loop

0

Estou executando meu script como script.sh 12345 12346 12347

for z in 1..$(seq 1 $#);
do
    echo "param $z is $($(echo $z))"; //Line 4
done;

Espero que o resultado seja o seguinte:

param 1 is 12345
param 2 is 12346
param 3 is 12347

Acho que estou perdendo algo na Linha 4.

    
por Spike 26.02.2018 / 08:38

2 respostas

4

O problema com $($(echo $z)) é que ele se expande, primeiro para $(1) (se $z for 1) e então o shell tenta executar 1 como um comando.

Assumindo bash :

params=( "$@" )

for (( i = 0; i < ${#params[@]}; ++i )); do
    printf 'Param %d is "%s"\n' "$i" "${params[i]}"
done

Executando:

$ bash script.sh a b c
Param 0 is "a"
Param 1 is "b"
Param 2 is "c"

Ou com /bin/sh :

i=0
while [ "$#" -gt 0 ]; do
    printf 'Param %d is "%s"\n' "$i" "$1"
    i=$(( i + 1 ))
    shift
done

Executando isso:

$ /bin/sh script.sh a b c
Param 0 is "a"
Param 1 is "b"
Param 2 is "c"

Isso se você realmente precisar enumerá-los explicitamente. Normalmente, seria apenas loop "$@" :

for param in "$@"; do
    printf 'Param: "%s"\n' "$param"
    # do other thing with "$param" here
done
    
por 26.02.2018 / 08:47
1
for z in 1..$(seq 1 $#);

Isso se expandirá para 1..1 , 2 , 3 para três parâmetros. seq já imprime os números como palavras distintas, e for não pode realmente gerar listas de números. A expansão do brace pode gerar listas de números, a sintaxe é {1..3} , mas no Bash ele não suporta variáveis dentro dele.

Então, isso pode ser escrito como

for z in $(seq $#) ; do ...                  # or 
for (( z=1 ; z <= $# ; z++ )) ; do ...

ou com chaves no ksh ou zsh:

for z in {1..$#} ; do  ... 

Se você quiser se referir a uma variável indiretamente, use ${!var} (no Bash), em que var contém o nome da variável, por exemplo,

echo "param number $z is ${!z}"

Como alternativa, você pode usar a notação de fatia em $@ (deve funcionar no Bash / ksh / zsh):

echo "param number $z is ${@:z:1}"

Mas, na verdade, apenas usar for x in "$@" para fazer o loop dos valores pode ser considerado mais idiomático. A numeração também é bastante simples de adicionar sem recursos específicos do shell:

i=1
for x in "$@" ; do 
    echo "param $i is $x"
    i=$((i+1))     
done
    
por 26.02.2018 / 11:15