[英]What is the difference between $* and $@
谁能简单解释一下
除了技术文档中描述的差异之外,最好使用一些示例显示:
假设我们有四个shell脚本test1.sh
:
#!/bin/bash
rm $*
test2.sh
:
#!/bin/bash
rm "$*"
test3.sh
:
#!/bin/bash
rm $@
test4.sh
:
#!/bin/bash
rm "$@"
(我在这里使用rm
而不是echo
,因为有了echo
,人们看不出差别)
我们使用以下命令行调用所有这些命令行,否则在一个空的目录中:
./testX.sh "Hello World" Foo Bar
对于test1.sh
和test3.sh
,我们收到以下输出:
rm: cannot remove ‘Hello’: No such file or directory
rm: cannot remove ‘World’: No such file or directory
rm: cannot remove ‘Foo’: No such file or directory
rm: cannot remove ‘Bar’: No such file or directory
这意味着,参数被视为一个完整的字符串,与空格连接,然后作为参数重新表示并传递给命令。 将参数转发给另一个命令时,这通常没有用。
使用test2.sh
,我们得到:
rm: cannot remove ‘Hello World Foo Bar’: No such file or directory
所以我们和test{1,3}.sh
,但这次,结果作为一个参数传递。
test4.sh
有一些新东西:
rm: cannot remove ‘Hello World’: No such file or directory
rm: cannot remove ‘Foo’: No such file or directory
rm: cannot remove ‘Bar’: No such file or directory
这意味着参数的传递方式与它们传递给脚本的方式相同。 将参数传递给其他命令时,这很有用。
区别是微妙的,但是在将参数传递给命令时会咬你,这些命令期望命令行中的某些点以及空间参与游戏时的信息。 这实际上是大多数炮弹的许多陷阱之一的一个很好的例子。
如果你没有在引号中加上$*
或$@
,则没有区别。 但是如果你把它们放在引号内(你应该这是一般的好习惯),那么$@
会将你的参数作为单独的参数传递,而$*
只会将所有参数作为单个参数传递。
使用这些脚本( foo.sh
和bar.sh
)进行测试:
>> cat bar.sh
echo "Arg 1: $1"
echo "Arg 2: $2"
echo "Arg 3: $3"
echo
>> cat foo.sh
echo '$* without quotes:'
./bar.sh $*
echo '$@ without quotes:'
./bar.sh $@
echo '$* with quotes:'
./bar.sh "$*"
echo '$@ with quotes:'
./bar.sh "$@"
现在这个例子应该让一切都清楚:
>> ./foo.sh arg1 "arg21 arg22" arg3
$* without quotes:
Arg 1: arg1
Arg 2: arg21
Arg 3: arg22
$@ without quotes:
Arg 1: arg1
Arg 2: arg21
Arg 3: arg22
$* with quotes:
Arg 1: arg1 arg21 arg22 arg3
Arg 2:
Arg 3:
$@ with quotes:
Arg 1: arg1
Arg 2: arg21 arg22
Arg 3: arg3
显然, "$@"
给出了我们通常想要的行为。
案例1: $*
和$@
附近没有报价:
两者都有相同的行为。
./bar.sh $*
=> bar.sh
将arg1
, arg2
和arg3
作为单独的参数
./bar.sh $@
=> bar.sh
将arg1
, arg2
和arg3
作为单独的参数
案例2:您使用$*
和$@
附近的报价:
./bar.sh "$*"
=> bar.sh
将arg1 arg2 arg3
作为单个参数获取
./bar.sh "$@"
=> bar.sh
将arg1
, arg2
和arg3
作为单独的参数获取
更重要的是, $*
也会忽略参数列表中的引号。 例如,如果你提供了./foo.sh arg1 "arg2 arg3"
,那么即便如此:
./bar.sh "$*"
=> bar.sh
仍将接收arg2
和arg3
作为单独的参数!
./bar.sh "$@"
=>将arg2 arg3
作为单个参数传递(这是您通常想要的)。
再次注意,只有在引号中放入$*
和$@
时才会出现这种差异。 否则他们有相同的行为。
官方文档: http : //www.gnu.org/software/bash/manual/bash.html#Special-Parameters
看到这里 :
$# Stores the number of command-line arguments that
were passed to the shell program.
$? Stores the exit value of the last command that was
executed.
$0 Stores the first word of the entered command (the
name of the shell program).
$* Stores all the arguments that were entered on the
command line ($1 $2 ...).
"$@" Stores all the arguments that were entered
on the command line, individually quoted ("$1" "$2" ...).
举个例子
./command -yes -no /home/username
so now..
$# = 3
$* = -yes -no /home/username
$@ = ("-yes" "-no" "/home/username")
$0 = ./command
$1 = -yes
$2 = -no
$3 = /home/username
引用时它们是不同的:
$ set "a b" c d
$ echo $#
3
$ set "$*"
$ echo $#
1
$ set "a b" c d
$ echo $#
3
$ set "$@"
$ echo $#
3
这里只有第二种形式保留参数计数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.