web-dev-qa-db-fra.com

Quelle est la différence entre "$ @" et "$ *" dans Bash?

Il me semble qu'ils stockent tous les deux tous les arguments de ligne de commande.

Y a-t-il donc une différence entre les deux?

63
Debugger

La différence est subtile; "$*" crée un argument séparé par le $IFS variable, tandis que "$@" se développera en arguments séparés. À titre d'exemple, considérons:

for i in "$@"; do echo "@ '$i'"; done
for i in "$*"; do echo "* '$i'"; done

Lorsqu'il est exécuté avec plusieurs arguments:

./testvar foo bar baz 'long arg'
@ 'foo'
@ 'bar'
@ 'baz'
@ 'long arg'
* 'foo bar baz long arg'

Pour plus de détails:

http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters

$*

S'étend aux paramètres positionnels, en commençant par un. Lorsque l'expansion se produit entre guillemets doubles, 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. C'est, "$*" est équivalent à "$1c$2c...", où c est le premier caractère de la valeur de la variable IFS. Si IFS n'est pas défini, les paramètres sont séparés par des espaces. Si IFS est nul, les paramètres sont joints sans séparateurs intermédiaires.

$@

S'étend aux paramètres positionnels, en commençant par un. Lorsque l'expansion se produit entre guillemets doubles, chaque paramètre se développe dans un mot distinct. C'est, "$@" est équivalent à "$1" "$2" .... Si l'expansion entre guillemets se produit dans un mot, l'expansion du premier paramètre est jointe à la partie de début du mot d'origine et l'expansion du dernier paramètre est jointe à la dernière partie du mot d'origine. Lorsqu'il n'y a pas de paramètres de position, "$@" et $@ s'étendre à rien (c'est-à-dire qu'ils sont supprimés).

95
Hudson

Une clé différence par rapport à mon POV est que "$@" conserve le nombre d'origine d'arguments. C'est la forme seulement qui le fait.

Par exemple, si le fichier my_script contient:

#!/bin/bash

main()
{
   echo 'MAIN sees ' $# ' args'
}

main $*
main $@

main "$*"
main "$@"

### end ###

et je le lance comme ceci:

my_script 'a b c' d e

J'obtiendrai cette sortie:

MAIN sees  5  args
MAIN sees  5  args
MAIN sees  1  args
MAIN sees  3  args
57
Art Swri