$ @在shell脚本中是什么意思?


Answers:


240

$@是传递给脚本的所有参数。

举例来说,如果你打电话./someScript.sh foo bar,然后$@将等于foo bar

如果您这样做:

./someScript.sh foo bar

然后里面someScript.sh引用:

umbrella_corp_options "$@"

该参数将传递给umbrella_corp_options每个参数,并用双引号引起来,从而允许调用者从空格中获取参数并将其传递。


1
如果我这样做,$ @将包含什么someScript.sh foo bar "boo far"
trusktr'4


7
$ @如果用双引号引起来,则是特殊的。然后,它将在三个参数“ foo”,“ bar”和“ boo far”中生成带引号的值列表(在您的情况下为trusktr)。
Alfe 2012年

4
虽然通常是这样,$@不一定来自传递给脚本的参数。set a b "x   y"; printf '(%s)' "$@"输出(a)(b)(x   y)
Peter.O 2012年

我更喜欢Alfe的答案,因为他给出了$@和之间的主要区别$*
-donleyp

106

$@与几乎相同$*,均表示“所有命令行参数”。它们通常用于简单地将所有参数传递给另一个程序(从而形成对该另一个程序的包装)。

当您的参数中带有空格(例如)并$@用双引号引起来时,就会显示出两种语法之间的差异:

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.

示例:呼叫

wrapper "one two    three" four five "six seven"

将导致:

"$@": 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

2
它们并不相同,使用IFS的$ *副作用也很明显,联机帮助页很明显,它不一定是空格。(如果两者相同,那么也许两者兼有,除了兼容性之外,没有其他意义。)
jørgensen2012年

6
不,他们不是。我在下面这样说两行:“两者之间的区别...”为了获得简短的句子并提高可读性,读者必须阅读一个以上的句子,然后才能作出判决:-/
Alfe

2
阿尔夫(Chris)克里斯托弗(Alfe),克里斯托弗(Christoffer)在“几乎”一词的插入使情况发生了变化,而又没有牺牲任何简洁性或可读性。实际上,正是由于对差异的细微强调,我才对这个答案(而不是公认的答案)投票赞成……-在意识到这几乎违背您的意愿之前!;)
Sz。

我认为这个词对于那些在阅读了第一句话之后立即做出判决的人来说实在是个地狱;-)从来没有违反我的意愿。我也很想为这些人写信。
Alfe

非常不清楚。wrappedProgram "$*"-> separated by single spaces.但在您的第二个示例中,它们之间没有空格。
Felix Dombek '18


13

$@在大多数情况下,使用纯手段“会尽最大努力伤害程序员”,因为在大多数情况下,这会导致单词分隔以及参数中的空格和其他字符的问题。

在(被猜测的)所有情况的99%中,需要将其括在""$@"中,该变量可用于可靠地遍历参数。

for a in "$@"; do something_with "$a"; done

4
您的行可以写为:用“ $ a”做某事;完成;-)
Alfe 2012年

1
@Alfe我知道;我只是忘记了它。认为它是for a in start_token "$@" end_token; do something_with "$a"; done:-)
glglgl 2012年

9

从手册中:

@

从一个开始扩展到位置参数。当在双引号内进行扩展时,每个参数都会扩展为单独的单词。也就是说,“ $ @”等效于“ $ 1”,“ $ 2”...。如果在单词中出现双引号扩展,则第一个参数的扩展与原始单词的开头部分连接在一起,并且最后一个参数的扩展与原始单词的最后一部分结合在一起。当没有位置参数时,“ $ @”和$ @扩展为空(即,它们被删除)。


1

含义。

简而言之,$@扩展为从调用方传递给函数或脚本的位置参数。它的含义取决于上下文:在函数内部,它扩展为传递给该函数的参数。如果在脚本中使用(不在函数的作用域内),它将扩展为传递给该脚本的参数。

$ cat my-sh
#! /bin/sh
echo "$@"

$ ./my-sh "Hi!"
Hi!
$ put () ( echo "$@" )
$ put "Hi!"
Hi!

分词。

现在,了解$@外壳中的行为时另一个至关重要的主题是单词拆分。Shell根据IFS变量的内容分割标记。默认值为\t\n; 即空格,制表符和换行符。

扩展"$@"为您提供了所传递参数的原始副本。但是,扩展$@并非总是如此。更具体地说,如果参数包含的字符IFS,则它们将拆分。


大多数时候,你会想什么用途"$@",不是$@

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.