$@ 在 shell 脚本中是啥意思?

Posted

技术标签:

【中文标题】$@ 在 shell 脚本中是啥意思?【英文标题】:What does $@ mean in a shell script?$@ 在 shell 脚本中是什么意思? 【发布时间】:2012-04-17 04:01:52 【问题描述】:

在 shell 脚本中,美元符号后跟 at 符号 (@) 是什么意思?

例如:

umbrella_corp_options $@

【问题讨论】:

@alfe 有一个更好的答案.. 希望你能接受它来帮助那些提出这个问题的人 【参考方案1】:

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

例如,如果您调用./someScript.sh foo bar,那么$@ 将等于foo bar

如果你这样做:

./someScript.sh foo bar

然后在someScript.sh里面参考:

umbrella_corp_options "$@"

这将被传递给umbrella_corp_options,每个单独的参数都用双引号括起来,允许从调用者那里获取带有空格的参数并传递它们。

【讨论】:

如果我使用someScript.sh foo bar "boo far",$@ 会包含什么? teaching.idallen.com/dat2330/04f/notes/shell_variables.txt 看看这个。 $@ 如果写在双引号中是特殊的。然后它将产生一个引用值列表,在你的例子中,trusktr,在三个参数“foo”、“bar”和“boo far”中。 虽然通常是这样,$@ 确实不一定来自传递给脚本的参数...例如; set a b "x   y"; printf '(%s)' "$@" 输出 (a)(b)(x   y) 我更喜欢 Alfe 的回答,因为他给出了 $@$* 之间的主要区别【参考方案2】:

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

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

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

【讨论】:

它们相同,并且手册页清楚地说明了使用 IFS 的 $* 的副作用——不一定是空格。 (如果它们相同,那么提供两者可能除了兼容性之外没有任何意义。) 不,他们不是。我在下面说了两行:“两者之间的区别......”为了获得简短的句子并提高可读性,读者必须阅读不止一个句子才能做出判断:-/ Alfe,Christoffer 在不牺牲任何简洁性或可读性的情况下插入“几乎”这个词产生了巨大的影响。事实上,我赞成这个答案(与接受的答案相反)正是由于对差异的微妙强调...... - 在意识到这几乎违背你的意愿之前! ;) 我认为这个词对那些在阅读第一句话后立即做出判决的人来说是天壤之别;-) 这从来没有违背我的意愿。我也很想为这些人写作。 非常不清楚。 wrappedProgram "$*" -> separated by single spaces. 但在您的第二个示例中,它们没有被单个空格分隔。【参考方案3】:

这些是命令行参数,其中:

$@ = 将所有参数存储在字符串列表中$* = 将所有参数存储为单个字符串$# = 存储参数数量

【讨论】:

(@iruvar 提到的上述不准确已修复。) 在这种情况下什么是“列表”? "$@" 实际上不是字符串列表,而是参数列表。【参考方案4】:

使用纯$@ 在大多数情况下意味着“尽可能地伤害程序员”,因为在大多数情况下,它会导致单词分隔以及参数中的空格和其他字符出现问题。

在(推测)99% 的情况下,需要将其包含在 " 中:"$@" 可用于可靠地迭代参数。

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

【讨论】:

你的行可以写成:for a;用“$a”做某事;完成;-) @Alfe 我知道;我只是忘记了。把它想象成for a in start_token "$@" end_token; do something_with "$a"; done :-)【参考方案5】:

意思。

简而言之,$@ 扩展为从调用者传递给函数脚本参数 >。其含义是context-dependent:在函数内部,它扩展为传递给该函数的参数。如果在脚本中(函数外)使用,它会扩展为传递给此类脚本的参数。

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

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

* 注意:分词。

shell 根据IFS 环境变量的内容拆分标记。它的默认值为 \t\n;即空格、制表符和换行符。扩展 "$@" 会为您提供传递参数的原始副本。扩展$@ 可能不会。更具体地说,任何包含 IFS 中存在的字符的参数都可能拆分为两个或多个参数或被截断。

因此,大多数时候您想要使用的是"$@",而不是$@

【讨论】:

【参考方案6】:

From the manual:

@

从一开始扩展到位置参数。当扩展出现在双引号内时,每个参数都扩展为一个单独的单词。即“$@”等价于“$1”“$2”……。如果双引号扩展出现在一个单词中,第一个参数的扩展与原单词的开头部分连接,而最后一个参数的扩展与原始单词的最后一部分相连。当没有位置参数时,"$@" 和 $@ 扩展为空(即,它们被删除)。

【讨论】:

【参考方案7】:

“传递给函数的所有参数”一开始让我很伤心。

它确实包含 $0,即被传递(是吗?)到程序中的脚本的名称,尽管是隐式的。

【讨论】:

以上是关于$@ 在 shell 脚本中是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

shell脚本中#是啥意思

$$在linux脚本中是啥意思? [复制]

string.unpack('<I2s2', data) 在 Lua 脚本中是啥意思?

shell脚本中的$*,$@和$#分别是啥意思?

Linux shell 脚本中, $@ 和$# 分别是啥意思?

UNIX shell 脚本中的“#!/bin/sh”行是啥意思?