Différence entre $@, $*, "$@" et "$*"

Article suivant: Sqlite, reconstruire la bdd pour l'alléger
Article précédent: Délégation d'événement en js

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

Commentaires

Aucun commentaire pour le moment :'(

Le système de commentaire passe par les issues de github et aucun n'est associée au billet. Vous pouvez faire votre commentaire dans une issue qui a comme titre celui du billet. Je me chargerai de les associer.

Revenir en haut