据我理解并阅读,$@
变成“arg1”“arg2”“arg3”。
但在引用的某些情况下似乎有一些奇怪的行为
测试1,$ @
$ function somefunc { sh -c "echo $@"; }
$ somefunc 1 2 3
> + somefunc 1 2 3
> + sh -c 'echo 1' 2 3
> 1
预期的输出是1 2 3,我得到的输出是1.现在我看到,由于某种原因,它似乎只传递echo 1
作为命令,但为什么"echo "1" "2" "3""
变成它?我可能已经预料到echo
,因为“之前的回声可能会在1之前被”关闭
测试2,$ *
$ function somefunc { sh -c "echo $*"; }
$ somefunc 1 2 3
> + somefunc 1 2 3
> + sh -c 'echo 1 2 3'
> 1 2 3
这非常明显且有效,只是为了确保。在所有$*
通过1 2 3
之后,而不是"1" "2" "3"
测试3,$ @和$ *
$ function somefunc { sh -c "echo $@ $*"; }
$ somefunc 1 2 3
> + somefunc 1 2 3
> + sh -c 'echo 1 2 3 1 2 3'
> 1 2 3 1 2 3
这似乎又奇怪了。但我不知道"echo "1" "2" "3" 1 2 3"
如何变成'echo 1 2 3 1 2 3'
并且不遵循只有"echo $@"
所做的“模式”。
测试4,$ @和字符串
$ function somefunc { sh -c "echo $@ hi"; }
$ somefunc 1 2 3
> + somefunc 1 2 3
> + sh -c 'echo 1' 2 '3 hi'
> 1
这再次遵循"echo $@"
的模式,甚至认为,正如我所看到的,它与"echo $@ $*"
几乎相同,因为$*
毕竟变成了一个字符串。 />
让我感到困惑的是它变成'echo 1' 2 '3 hi'
,第一个测试会建议'echo 1' 2 3 hi
(没有'
围绕3 hi
测试5,$ @和$ var
$ var="hi"
> + var=hi
$ function somefunc { sh -c "echo $@ $var"; }
$ somefunc 1 2 3
> + somefunc 1 2 3
> + sh -c 'echo 1 2 3 hi'
> 1 2 3 hi
这再次起作用。所以$@
似乎有效,如果另一个变量跟随它。
使用su user -c
或bash -c
代替sh -c
也可以进行测试,所以我想也会执行下一个给定参数的所有其他命令。
我现在似乎已经从中获得了某种行为,
但我仍然不明白这种行为
我在这里缺少什么?
答案 0 :(得分:2)
sh language spec可以说$@
:
从1开始扩展到位置参数。当扩展发生在双引号内,并且执行字段拆分(参见字段拆分)时,每个位置参数应作为单独的字段扩展,并规定第一个参数的扩展仍应与开头部分连接原始单词(假设扩展参数嵌入在单词中),最后一个参数的扩展仍然与原始单词的最后部分连接。如果没有位置参数,“@”的扩展将产生零字段,即使“@”是双引号。
这意味着位置参数为"echo $@ $*"
,1
,2
的字符串3
应扩展为"echo 1" "2" "3 1 2 3"
,以便您的测试3应该输出字符串1
。 bash错误地将字符串扩展为"echo 1 2 3 1 2 3"
并输出1 2 3 1 2 3
这一事实表明bash中存在错误。
处理这个(又一个)sh语法规则的奇怪之处的常用技巧是当它是一个不同的单词时,只在双引号中使用$ @。换句话说,可以写"$@"
,但不要将$@
放在双引号中,除非它是双引号内的唯一内容。
答案 1 :(得分:1)
使用@BrianSwift的提示,一切都非常有意义,除了 Test3 (这里,不我们得到三个参数的情况,第一个参数的前缀是'echo '
,第三个后缀为' $*'
。相反,结果是一个参数。)
但这可能是因为$@
和$*
都是“特殊”变量,而shell中存在特殊代码。我假设$*
的存在只是覆盖@BrianSwift注意到的特殊行为,因为$*
稍后会被评估。
尝试交换订单:somefunc() { sh -x "echo $* $@"; }
。您将再次获得split-with-prefix-and-suffix行为,这似乎支持我的上述假设。
总而言之,除了Test3的行为可能有点“未记录”之外,所有内容都可以通过对手册的引用来解释。
答案 2 :(得分:0)
据我了解并阅读,$ @变成“arg1”“arg2”“arg3”。
不,"$@"
变为"arg1" "arg2" "arg3"
。引号很重要。