Primeiro, observe que $@sem aspas não faz sentido e não deve ser usado. $@deve ser usado apenas entre aspas ( "$@") e em contextos de lista.
for i in "$@" se qualifica como um contexto de lista, mas aqui, para fazer um loop sobre os parâmetros posicionais, a forma canônica, mais portátil e mais simples é:
for i
do something with "$i"
done
Agora, para percorrer os elementos a partir do segundo, a maneira canônica e mais portátil é usar shift:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Depois shift, o que costumava ser $1foi removido da lista (mas salvou-lo em $first_arg) eo que costumava ser no $2agora está em $1. Os parâmetros posicionais foram trocados de 1 posição para a esquerda (use shift 2para deslocar 2 ...). Então, basicamente, nosso loop está repetindo o que costumava ser o segundo argumento até o último.
Com bash(e zshe ksh93, mas é isso), uma alternativa é fazer:
for i in "${@:2}"
do something with "$i"
done
Mas observe que não é uma shsintaxe padrão, portanto, não deve ser usado em um script que comece com #! /bin/sh -.
Em zshou yash, você também pode:
for i in "${@[3,-3]}"
do something with "$i"
done
para fazer um loop do terceiro para o terceiro último argumento.
In zsh, $@também é conhecido como $argvarray. Portanto, para exibir elementos do início ou do fim das matrizes, você também pode:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shifttambém pode ser escrito 1=()em zsh)
Em bash, você só pode atribuir aos $@elementos com o setbuiltin, para destacar três elementos no final, isso seria algo como:
set -- "${@:1:$#-3}"
E para passar do terceiro para o terceiro último:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIX, para exibir os três últimos elementos "$@", você precisará usar um loop:
n=$(($# - 3))
for arg do
[ "$n" -gt 0 ] && set -- "$@" "$arg"
shift
n=$((n - 1))
done
for ((i=2; i<=$#; i++)); do something with "${!i}"; done