访问 bash 命令行参数 $@ 与 $*

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12314451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:38:32  来源:igfitidea点击:

Accessing bash command line args $@ vs $*

bashcommand-line-arguments

提问by Oz123

In many SO questions and bash tutorials I see that I can access command line args in bash scripts in two ways:

在许多 SO 问题和 bash 教程中,我看到我可以通过两种方式访问​​ bash 脚本中的命令行参数:

$ ~ >cat testargs.sh 
#!/bin/bash

echo "you passed me" $*
echo "you passed me" $@

Which results in:

结果是:

$ ~> bash testargs.sh arg1 arg2
you passed me arg1 arg2
you passed me arg1 arg2

What is the difference between $*and $@?
When should one use the former and when shall one use the latter?

$*和 和有$@什么区别?
什么时候应该使用前者,什么时候应该使用后者?

回答by glenn Hymanman

The difference appears when the special parameters are quoted. Let me illustrate the differences:

引用特殊参数时会出现差异。让我来说明差异:

$ set -- "arg  1" "arg  2" "arg  3"

$ for word in $*; do echo "$word"; done
arg
1
arg
2
arg
3

$ for word in $@; do echo "$word"; done
arg
1
arg
2
arg
3

$ for word in "$*"; do echo "$word"; done
arg  1 arg  2 arg  3

$ for word in "$@"; do echo "$word"; done
arg  1
arg  2
arg  3


one further example on the importance of quoting: note there are 2 spaces between "arg" and the number, but if I fail to quote $word:

关于引用重要性的另一个例子:注意“arg”和数字之间有 2 个空格,但如果我没有引用 $word:

$ for word in "$@"; do echo $word; done
arg 1
arg 2
arg 3

and in bash, "$@"is the "default" list to iterate over:

在 bash 中,"$@"是要迭代的“默认”列表:

$ for word; do echo "$word"; done
arg  1
arg  2
arg  3

回答by Serge Stroobandt

A nice handy overview table from the Bash Hackers Wiki:

来自Bash Hackers Wiki 的一个方便的概览表:

$* versus $@ table

$* 与 $@ 表

where cin the third row is the first character of $IFS, the Internal Field Separator, a shell variable.

其中c第三行是 的第一个字符$IFS,内部字段分隔符,一个 shell 变量。

If the arguments are to be stored in a script variableand the arguments are expected to contain spaces, I wholeheartedly recommend employing a "$*"trick with the internal field separator $IFSset to tab.

如果参数要存储在脚本变量中并且参数应该包含空格,我衷心建议使用"$*"将内部字段分隔符$IFS设置为 tab技巧

回答by Muffo

$*

$*

Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable. That is, "$*" is equivalent to "$1c$2c...", where c is the first character of the value of the IFS variable. If IFS is unset, the parameters are separated by spaces. If IFS is null, the parameters are joined without intervening separators.

扩展到位置参数,从 1 开始。当扩展发生在双引号内时,它扩展为单个单词,每个参数的值由 IFS 特殊变量的第一个字符分隔。也就是说,“$*”等价于“$1c$2c...”,其中c是IFS变量值的第一个字符。如果未设置 IFS,则参数以空格分隔。如果 IFS 为空,则连接参数时不插入分隔符。

$@

$@

Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" ... If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word. When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).

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

Source: Bash man

来源:Bash man

回答by rkosegi

$@ is same as $*, but each parameter is a quoted string, that is, the parameters are passed on intact, without interpretation or expansion. This means, among other things, that each parameter in the argument list is seen as a separate word.

$@ 与 $* 相同,但每个参数都是一个带引号的字符串,即参数原封不动地传递,没有解释或扩展。这意味着,除其他外,参数列表中的每个参数都被视为一个单独的词。

Of course, "$@" should be quoted.

当然,“$@”应该被引用。

http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST

http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST

回答by stefansson

This example let may highlight the differ between "at" and "asterix" while we using them. I declared two arrays "fruits" and "vegetables"

这个例子让我们在使用它们时突出显示“at”和“asterix”之间的区别。我声明了两个数组“水果”和“蔬菜”

fruits=(apple pear plumm peach melon)            
vegetables=(carrot tomato cucumber potatoe onion)

printf "Fruits:\t%s\n" "${fruits[*]}"            
printf "Fruits:\t%s\n" "${fruits[@]}"            
echo + --------------------------------------------- +      
printf "Vegetables:\t%s\n" "${vegetables[*]}"    
printf "Vegetables:\t%s\n" "${vegetables[@]}"    

See the following result the code above:

看到上面的代码结果如下:

Fruits: apple pear plumm peach melon
Fruits: apple
Fruits: pear
Fruits: plumm
Fruits: peach
Fruits: melon
+ --------------------------------------------- +
Vegetables: carrot tomato cucumber potatoe onion
Vegetables: carrot
Vegetables: tomato
Vegetables: cucumber
Vegetables: potatoe
Vegetables: onion