Différence entre $@, $*, "$@" et "$*"
Dans un script shell, il existe 2 variables pour accéder aux paramètres de la commande (aussi nommées argv dans pas mal d’autres langages): $* et $@.
$*est une variable ce qu’il y a de plus normale et ne diffère pas d’une autre variable. Cependant, le comportement des variables diffère en fonction du shell, notamment sur zsh (j’y reviens après).$@est une variable au comportement différent entre les shells.
Sur bash, il n’y a aucune différence entre $* et $@. Par contre, sur ksh et zsh, $@ représente un tableau d’arguments. Il faut savoir que sur bash, utiliser une variable sans guillemet revient à créer autant d’arguments qu’il y a de mots. Les mots sont séparés en fonction des caractères dans $IFS (la variable contient par défaut : espace, tabulation et saut de ligne). C’est pour cela qu’il est conseillé d’entourer ces variables de guillemets doubles.
Un petit exemple pour comprendre :).
a='a b c'
for v in $a ; do
echo $v
done
> a
> b
> c
Le résultat est 3 lignes pour 1 paramètre, la chaîne 'a b c' contenant des espaces s’est fait couper. Ce n’est pas le cas pour zsh qui ne fait pas cette césure (raison historique, j’y reviens à la fin).
Maintenant il reste "$*" et "$@" qui ne diffèrent pas entre les shells.
"$*"correspond à une seule chaîne, tout est géré en un seul bloc."$@"représente les paramètres réels. C’est identique à$@avec ksh et zsh.
Démonstration
# test.sh
for v in XXX ; do
echo $v
done
Le code ci-dessus est utilisé avec ./test.s 'a b' c et pour lequel XXX est remplacé par une des 4 variables précédemment citées.
| XXX | bash | ksh | zsh |
|---|---|---|---|
$* |
a b c |
a b c |
a b c |
$@ |
a b c |
a b c |
a b c |
"$*" |
a b c | a b c | a b c |
"$@" |
a b c |
a b c |
a b c |
Pour que zsh boucle sur des mots, il faut ajouter un flag à la variable (${=*} ou $=*), comme ci-dessous.
a='a b c';
for v in ${=a} ; do
echo $v
done