web-dev-qa-db-fra.com

Quelle est la différence entre $ @ et $ *

Selon cette page , $ @ et $ * font à peu près la même chose:

The $@ holds list of all arguments passed to the script. 
The $* holds list of all arguments passed to the script.

Après avoir recherché tous les meilleurs hits dans google, je ne trouve aucune explication pourquoi il y aurait 2 syntaxes apparemment en double.

Ils semblent fonctionner de la même manière dans mes scripts.

cat foo.sh
#!/bin/bash
echo The parameters passed in are $@
echo The parameters passed in are $*

./foo.sh herp derp
The parameters passed in are herp derp
The parameters passed in are herp derp
  1. Est-ce que l'un est préféré à l'autre?
  2. Pourquoi y a-t-il 2 variables intégrées pour faire exactement la même chose?

Sources supplémentaires
bash.cyberciti.biz

70
spuder

Ce ne sont pas les mêmes. $* est une chaîne unique, tandis que $@ est un tableau réel. Pour voir la différence, exécutez le script suivant comme ceci:

 > ./test.sh one two "three four"

Le scénario:

#!/bin/bash

echo "Using \"\$*\":"
for a in "$*"; do
    echo $a;
done

echo -e "\nUsing \$*:"
for a in $*; do
    echo $a;
done

echo -e "\nUsing \"\$@\":"
for a in "$@"; do
    echo $a;
done

echo -e "\nUsing \$@:"
for a in $@; do
    echo $a;
done              

Les quatre cas sont:

Using "$*":
one two three four

Ici, les paramètres sont considérés comme une longue chaîne entre guillemets. Non cité:

Using $*:
one
two
three
four

La chaîne est divisée en mots par la boucle for.

Using "$@":
one
two
three four

Cela traite chaque élément de $ @ comme une chaîne entre guillemets.

Using $@:
one
two
three
four

Cela traite chaque élément comme une chaîne sans guillemets, donc le dernier est à nouveau divisé par ce qui équivaut à for three four.

100
goldilocks

La différence vient de la façon dont ils sont développés.

$* se développe en un seul argument avec tous les éléments délimités par des espaces (en fait, le premier caractère de $IFS).
$@ se développe en plusieurs arguments.

Par exemple

#!/bin/bash
echo "With *:"
for arg in "$*"; do echo "<$arg>"; done
echo
echo "With @:"
for arg in "$@"; do echo "<$arg>"; done

$ /tmp/test.sh 1  2 "3  4"
With *:
<1 2 3  4>

With @:
<1>
<2>
<3  4>
14
Patrick

Vous pouvez consulter Bash Beginners Guide pour plus d'informations. Ceux-ci font à peu près la même chose avec la différence de séparation:

$* - S'étend aux paramètres de position, 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.

$@ - S'étend aux paramètres de position, en commençant par un. Lorsque l'expansion se produit entre guillemets doubles, chaque paramètre se développe dans un mot distinct.

Mais à moins que vous ne définissiez IFS sur une valeur autre que celle par défaut, il pourrait sembler identique.

3
Karlson

Est-ce que l'un est préféré à l'autre?

Une réponse courte est "$@".

Si vous les utilisez sans guillemets, ce sont les mêmes. Dans ce cas, personne n'est préféré à l'autre. Mais je vous suggère de toujours les utiliser avec des guillemets doubles, sauf que vous savez exactement ce que vous voulez.

Pourquoi y a-t-il 2 variables intégrées pour faire exactement la même chose?

Il n'y a aucune différence entre $* et $@, mais "$@" et "$*" avoir.

Vous pouvez voir ma réponse dans cet article pour voir en quoi ils sont différents.

1
cuonglm