Tout d'abord, notez que $@
sans guillemets n'a pas de sens et ne doit pas être utilisé. $@
doit être utilisé uniquement entre guillemets ( "$@"
) et dans des contextes de liste.
for i in "$@"
qualifie comme un contexte de liste, mais ici, pour boucler sur les paramètres de position, la forme canonique, la plus portable et la plus simple est:
for i
do something with "$i"
done
Maintenant, pour boucler sur les éléments à partir du second, la manière la plus canonique et la plus portable est d’utiliser shift
:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Après shift
, ce qui était auparavant $1
a été supprimé de la liste (mais nous l'avons enregistré $first_arg
) et ce qui était auparavant $2
est maintenant $1
. Les paramètres de position ont été décalés 1
à gauche (utilisez shift 2
pour décaler de 2 ...). Donc, fondamentalement, notre boucle boucle de ce qui était le deuxième argument au dernier.
Avec bash
(et zsh
et ksh93
, mais c'est tout), une alternative est de faire:
for i in "${@:2}"
do something with "$i"
done
Mais notez que ce n'est pas une sh
syntaxe standard et qu'il ne faut donc pas l'utiliser dans un script qui commence par #! /bin/sh -
.
En zsh
ou yash
, vous pouvez aussi faire:
for i in "${@[3,-3]}"
do something with "$i"
done
faire une boucle du 3ème au 3ème dernier argument.
Dans zsh
, $@
est également connu sous le nom de $argv
tableau. Donc, pour faire apparaître des éléments au début ou à la fin des tableaux, vous pouvez également faire:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shift
peut également être écrit 1=()
dans zsh
)
Dans bash
, vous ne pouvez affecter que les $@
éléments avec la fonction set
intégrée. Par conséquent, pour extraire 3 éléments à la fin, cela ressemblerait à quelque chose comme:
set -- "${@:1:$#-3}"
Et pour boucler du 3 au 3 dernier:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIXly, pour faire apparaître les 3 derniers éléments de "$@"
, vous devez utiliser une boucle:
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