Accéder à la ligne de commande bash args $ @ vs $ *

Dans de nombreuses questions et didacticiels SO, je vois que je peux accéder aux arguments de la ligne de commande dans les scripts bash de deux manières:

$ ~ >cat testargs.sh #!/bin/bash echo "you passed me" $* echo "you passed me" $@ 

Qui aboutit à:

 $ ~> bash testargs.sh arg1 arg2 you passed me arg1 arg2 you passed me arg1 arg2 

Quelle est la différence entre $* et $@ ?
Quand faut-il utiliser le premier et quand utiliser le second?

La différence apparaît lorsque les parameters spéciaux sont cités. Permettez-moi d’illustrer les différences:

 $ set -- "arg 1" "arg 2" "arg 3" $ for word in $*; do echo "$word"; done arg 1 arg 2 arg 3 $ for word in $@; do echo "$word"; done arg 1 arg 2 arg 3 $ for word in "$*"; do echo "$word"; done arg 1 arg 2 arg 3 $ for word in "$@"; do echo "$word"; done arg 1 arg 2 arg 3 

un autre exemple sur l’importance de citer: notez qu’il y a 2 espaces entre “arg” et le nombre, mais si je ne cite pas $ word:

 $ for word in "$@"; do echo $word; done arg 1 arg 2 arg 3 

et dans bash, "$@" est la liste “par défaut” pour parcourir:

 $ for word; do echo "$word"; done arg 1 arg 2 arg 3 

Une belle vue d’ensemble pratique du wiki Bash Hackers :

$ * versus $ @ table

Si les arguments doivent être stockés dans une variable de script et que les arguments sont supposés contenir des espaces, je recommande vivement d’utiliser une astuce "$*" avec le séparateur de champs interne $IFS défini sur tab .

$ *

S’étend aux parameters de position, à partir de un. Lorsque l’expansion se produit entre guillemets, elle se développe en un seul mot avec la valeur de chaque paramètre séparée par le premier caractère de la variable spéciale IFS. En d’autres termes, “$ *” est équivalent à “$ 1c $ 2c …”, où c est le premier caractère de la valeur de la variable IFS. Si IFS est désactivé, les parameters sont séparés par des espaces. Si IFS est nul, les parameters sont joints sans séparateurs intermédiaires.

$ @

S’étend aux parameters de position, à partir de un. Lorsque l’expansion se produit entre guillemets, chaque paramètre se développe en un mot distinct. C’est-à-dire que “$ @” est équivalent à “$ 1” “$ 2” … Si l’expansion entre guillemets se produit dans un mot, l’expansion du premier paramètre est jointe à la partie initiale du mot d’origine, et l’expansion du dernier paramètre est joint à la dernière partie du mot d’origine. Lorsqu’il n’y a pas de parameters de position, “$ @” et $ @ ne développent rien (c’est-à-dire qu’ils sont supprimés).

Source: Bash Man

$ @ est identique à $ *, mais chaque paramètre est une chaîne entre guillemets, c’est-à-dire que les parameters sont transmis intacts, sans interprétation ni extension. Cela signifie, entre autres choses, que chaque paramètre de la liste d’arguments est considéré comme un mot distinct.

Bien sûr, “$ @” devrait être cité.

http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST