在Shell脚本中,变量内部和外部的"&&"有什么区别?

3

仅出于好奇:

A="echo hi"
B="echo hello"
C="$A && $B"

echo $C // prints "echo hi && echo hello"
$C
echo "$A && $B" // prints "echo hi && echo hello"
$A && $B

我本以为这会以相同的方式工作。但是它展示了不同的结果:

echo hi && echo hello
hi && echo hello
echo hi && echo hello
hi
hello
为什么?
1个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
7

非常简短的回答

阅读BashFAQ#50

稍微简短的回答

变量扩展不会经过所有解析步骤(如果它们确实这样做,那么在bash中安全地处理不受信任的数据将是不可能的)。未引用的扩展仅通过字符串拆分和通配符扩展进行 - 这些阶段将字符串拆分成多个部分,并将这些部分作为通配符求值,但是不会将这些部分识别为语法。引用扩展被逐字替换,这意味着它们保留为字符串,不会改变。

因此:

echo $C         # runs: "echo" "echo " "hi" "&&" "echo" "hello"
$C              # runs: "echo " "hi" "&&" "echo" "hello"
echo "$A && $B" # runs: "echo" "echo hi && echo hello"
$A && $B        # runs: "echo" "hi" && "echo" "hello"
请注意,在上一个示例中,&&没有被引用。这表示它被解析为语法,而不是数据。作为语法,&&作为命令分隔符(而作为数据,它只是传递给echo)。

很好的答案。这就是为什么你永远不应该把你的代码放在变量里面的原因。 - viz
1
可以使用eval强制执行完整的解析步骤,但这会引起自己的问题(请参见[BashFAQ#48](http://mywiki.wooledge.org/BashFAQ/048))。 - Charles Duffy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,