微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

shell – $@变量的奇怪行为

据我了解并阅读它,$@变成“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“”转进去?我可能已经预料到回声,因为“之前的回声可能会在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也可以进行测试,所以我想也会执行下一个给定参数的所有其他命令.

我现在似乎已经从中获得某种行为,
但我仍然不明白这种行为.
在这里错过了什么?

解决方法

关于$@,sh language spec有这个说法:

从1开始扩展到位置参数.当扩展发生在双引号内,并且执行字段拆分(参见字段拆分)时,每个位置参数应作为单独的字段扩展,并规定第一个参数的扩展仍应与开头部分连接原始单词(假设扩展参数嵌入在单词中),最后一个参数的扩展仍然与原始单词的最后部分连接.如果没有位置参数,’@’的扩展将产生零场,即使’@’是双引号.

这意味着位置参数为1,2,3的字符串“echo $@ $*”应扩展为“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语法规则的奇怪之处的常用技术是当它是一个不同的单词时,只在双引号中使用$@.换句话说,可以写“$@”,但不要将$@放在双引号中,除非它是双引号内的唯一内容.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐