$@correspond à tous les paramètres passés au script.
Par exemple, si vous appelez, ./someScript.sh foo baralors $@sera égal à foo bar.
Si tu fais:
./someScript.sh foo bar
puis someScript.shréférence intérieure :
umbrella_corp_options "$@"
celui-ci sera transmis umbrella_corp_optionsavec chaque paramètre individuel entre guillemets, permettant de prendre des paramètres avec un espace vide de l'appelant et de les transmettre.
$ @ est spécial s'il est écrit entre guillemets. Ensuite, il en résultera une liste de valeurs entre guillemets, dans votre cas, trusktr, dans les trois arguments "foo", "bar" et "boo far".
Alfe
5
Bien que ce soit généralement le cas, $@ne vient pas nécessairement des paramètres passés au script ... par exemple; set a b "x y"; printf '(%s)' "$@"sorties(a)(b)(x y)
Peter.O
2
J'aime mieux la réponse d'Alfe parce qu'il donne la principale différence entre $@et$*
donleyp
114
$@est presque le même que $*, les deux signifiant "tous les arguments de ligne de commande". Ils sont souvent utilisés pour simplement passer tous les arguments à un autre programme (formant ainsi une enveloppe autour de cet autre programme).
La différence entre les deux syntaxes apparaît lorsque vous avez un argument avec des espaces (par exemple) et mis $@entre guillemets:
wrappedProgram "$@"# ^^^ this is correct and will hand over all arguments in the way# we received them, i. e. as several arguments, each of them# containing all the spaces and other uglinesses they have.
wrappedProgram "$*"# ^^^ this will hand over exactly one argument, containing all# original arguments, separated by single spaces.
wrappedProgram $*
# ^^^ this will join all arguments by single spaces as well and# will then split the string as the shell does on the command# line, thus it will split an argument containing spaces into# several arguments.
Exemple: appel
wrapper "one two three" four five "six seven"
aura pour résultat:
"$@": wrappedProgram "one two three" four five "six seven"
"$*": wrappedProgram "one two three four five six seven"
^^^^ These spaces are part of the first
argument and are not changed.
$*: wrappedProgram one two three four five six seven
Ce ne sont pas les mêmes, et la page de manuel est claire sur les effets secondaires de $ * en utilisant IFS - qui n'est pas nécessairement un espace. (S'ils étaient les mêmes, il n'y aurait aucun intérêt, autre que la compatibilité peut-être, à offrir les deux.)
jørgensen
7
Non ils ne sont pas. Et je l'ai dit deux lignes ci-dessous: "La différence entre les deux ..." Pour obtenir des phrases courtes et améliorer la lisibilité, le lecteur doit lire plus d'une phrase avant de rendre un verdict: - /
Alfe
2
Alfe, l'insertion par Christoffer de ce mot «presque» a fait une sacrée différence, sans sacrifier aucune lacune ni lisibilité. En fait, j'ai voté pour cette réponse (par opposition à celle acceptée) exactement en raison de cette subtile accentuation de la différence ... - avant de réaliser que c'était presque contre votre volonté! ;)
Sz.
Je pense que ce mot a fait une sacrée différence pour les gens qui ont rendu un verdict juste après avoir lu la première phrase ;-) et cela n'a jamais été contre ma volonté. J'aimerais vraiment écrire aussi pour ces personnes.
Alfe
Très peu clair. wrappedProgram "$*"-> separated by single spaces.mais dans votre 2ème exemple, ils ne sont pas séparés par des espaces simples.
Felix Dombek
39
Voici les arguments de ligne de commande où:
$@= stocke tous les arguments dans une liste de chaînes $*= stocke tous les arguments sous forme de chaîne unique $#= stocke le nombre d'arguments
(L'inexactitude ci-dessus mentionnée par @iruvar a été corrigée.)
Mateen Ulhaq
13
L'utilisation d'un $@moyen pur dans la plupart des cas "fait mal au programmeur aussi fort que vous le pouvez", car dans la plupart des cas, cela conduit à des problèmes de séparation des mots et d'espaces et autres caractères dans les arguments.
Dans (supposé) 99% de tous les cas, il est nécessaire de l'inclure dans ": "$@"est ce qui peut être utilisé pour itérer de manière fiable sur les arguments.
S'étend aux paramètres de position, en commençant par un. Lorsque l'expansion se produit entre guillemets, chaque paramètre se développe en un mot distinct. Autrement dit, "$ @" équivaut à "$ 1" "$ 2" .... Si le développement entre guillemets doubles se produit dans un mot, le développement du premier paramètre est joint à la partie de début du mot d'origine, et le 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'étendent à rien (c'est-à-dire qu'ils sont supprimés).
En bref, $@s'étend aux arguments positionnels passés de l'appelant à une fonction ou à un script . Sa signification dépend du contexte : à l'intérieur d'une fonction, elle s'étend aux arguments passés à une telle fonction. S'il est utilisé dans un script (pas dans la portée d'une fonction), il s'étend aux arguments passés à ce script.
Maintenant, un autre sujet qui est d'une importance primordiale pour comprendre comment $@se comporte dans le shell est le fractionnement de mots . Le shell divise les jetons en fonction du contenu de la IFSvariable. Sa valeur par défaut est \t\n; c'est-à-dire, espace blanc, tabulation et nouvelle ligne.
L'expansion "$@"vous donne une copie parfaite des arguments passés. Cependant, l'expansion $@ne le sera pas toujours. Plus précisément, si les arguments contiennent des caractères de IFS, ils seront séparés.
La plupart du temps, ce que vous voudrez utiliser ne l'est "$@"pas $@.
Réponses:
$@
correspond à tous les paramètres passés au script.Par exemple, si vous appelez,
./someScript.sh foo bar
alors$@
sera égal àfoo bar
.Si tu fais:
puis
someScript.sh
référence intérieure :umbrella_corp_options "$@"
celui-ci sera transmis
umbrella_corp_options
avec chaque paramètre individuel entre guillemets, permettant de prendre des paramètres avec un espace vide de l'appelant et de les transmettre.la source
someScript.sh foo bar "boo far"
?$@
ne vient pas nécessairement des paramètres passés au script ... par exemple;set a b "x y"; printf '(%s)' "$@"
sorties(a)(b)(x y)
$@
et$*
$@
est presque le même que$*
, les deux signifiant "tous les arguments de ligne de commande". Ils sont souvent utilisés pour simplement passer tous les arguments à un autre programme (formant ainsi une enveloppe autour de cet autre programme).La différence entre les deux syntaxes apparaît lorsque vous avez un argument avec des espaces (par exemple) et mis
$@
entre guillemets:wrappedProgram "$@" # ^^^ this is correct and will hand over all arguments in the way # we received them, i. e. as several arguments, each of them # containing all the spaces and other uglinesses they have. wrappedProgram "$*" # ^^^ this will hand over exactly one argument, containing all # original arguments, separated by single spaces. wrappedProgram $* # ^^^ this will join all arguments by single spaces as well and # will then split the string as the shell does on the command # line, thus it will split an argument containing spaces into # several arguments.
Exemple: appel
aura pour résultat:
la source
wrappedProgram "$*"
->separated by single spaces.
mais dans votre 2ème exemple, ils ne sont pas séparés par des espaces simples.Voici les arguments de ligne de commande où:
$@
= stocke tous les arguments dans une liste de chaînes$*
= stocke tous les arguments sous forme de chaîne unique$#
= stocke le nombre d'argumentsla source
L'utilisation d'un
$@
moyen pur dans la plupart des cas "fait mal au programmeur aussi fort que vous le pouvez", car dans la plupart des cas, cela conduit à des problèmes de séparation des mots et d'espaces et autres caractères dans les arguments.Dans (supposé) 99% de tous les cas, il est nécessaire de l'inclure dans
"
:"$@"
est ce qui peut être utilisé pour itérer de manière fiable sur les arguments.for a in "$@"; do something_with "$a"; done
la source
for a in start_token "$@" end_token; do something_with "$a"; done
:-)À partir du manuel:
la source
Sens.
En bref,
$@
s'étend aux arguments positionnels passés de l'appelant à une fonction ou à un script . Sa signification dépend du contexte : à l'intérieur d'une fonction, elle s'étend aux arguments passés à une telle fonction. S'il est utilisé dans un script (pas dans la portée d'une fonction), il s'étend aux arguments passés à ce script.$ cat my-sh #! /bin/sh echo "$@" $ ./my-sh "Hi!" Hi!
$ put () ( echo "$@" ) $ put "Hi!" Hi!
Partage de mots.
Maintenant, un autre sujet qui est d'une importance primordiale pour comprendre comment
$@
se comporte dans le shell est le fractionnement de mots . Le shell divise les jetons en fonction du contenu de laIFS
variable. Sa valeur par défaut est\t\n
; c'est-à-dire, espace blanc, tabulation et nouvelle ligne.L'expansion
"$@"
vous donne une copie parfaite des arguments passés. Cependant, l'expansion$@
ne le sera pas toujours. Plus précisément, si les arguments contiennent des caractères deIFS
, ils seront séparés.La plupart du temps, ce que vous voudrez utiliser ne l'est
"$@"
pas$@
.la source