Bash中"$ @"和"$*"有什么区别?

Deb*_*ger 65 variables bash command-line-arguments

在我看来,它们都存储了所有命令行参数.

两者之间有区别吗?

Hud*_*son 97

差异很微妙; "$*"创建一个由$IFS变量"$@"分隔的参数,同时将扩展为单独的参数.例如,考虑:

for i in "$@"; do echo "@ '$i'"; done
for i in "$*"; do echo "* '$i'"; done
Run Code Online (Sandbox Code Playgroud)

使用多个参数运行时:

./testvar foo bar baz 'long arg'
@ 'foo'
@ 'bar'
@ 'baz'
@ 'long arg'
* 'foo bar baz long arg'
Run Code Online (Sandbox Code Playgroud)

更多细节:

http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters

$*

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

$ @

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

  • 如果$ @和$*没有放入双引号(""),则展开行为看起来相同. (6认同)

Art*_*wri 58

与我的POV的一个主要区别是"$@"保留了原始的参数数量.这是唯一的形式.

例如,如果文件my_script包含:

#!/bin/bash

main()
{
   echo 'MAIN sees ' $# ' args'
}

main $*
main $@

main "$*"
main "$@"

### end ###
Run Code Online (Sandbox Code Playgroud)

我像这样运行它:

my_script 'a b c' d e
Run Code Online (Sandbox Code Playgroud)

我会得到这个输出:

MAIN sees  5  args
MAIN sees  5  args
MAIN sees  1  args
MAIN sees  3  args
Run Code Online (Sandbox Code Playgroud)

  • @Totem我假设你说'parens'但是意思是双引号."$*"和$*之间的区别在于引号将$*的扩展保持为单个字符串,而没有引号则允许将$*的部分视为单个项目.这是双引号的一般含义; 行为不是特定于$*和$ @.另外,单引号和双引号之间的区别在于替换(例如$*的扩展)是用双引号执行的,但不是在单引号内执行.('**'的结果只是$*,2个字符的字面值.) (2认同)