bash 如何解释条件条件中没有周围空格的等于运算符?

bash 如何解释条件条件中没有周围空格的等于运算符?

以下脚本的行为与我的预期不同。在条件语句中的“=”周围添加空格使其按照我想要的方式执行,但这让我思考,它在条件语句中实际上在做什么?

#!/bin/bash
S1='foo'
S2='bar'
if [ $S1=$S2 ];
then
    echo "S1('$S1') is equal to S2('$S2')
fi
echo $S1
echo $S2

输出是:

S1('foo') is equal to S2('bar')
foo
bar

S1 和 S2 的内容不会改变它们被分配的内容,因此 = 不执行分配。

答案1

记住这[实际上是一个命令,也可以作为test.在 bash 中,就像在大多数其他类似 Bourne 的 shell 中一样,它是一个内置命令,因此您可以使用info bash [或 通过在内部搜索来查看文档man bash(也在man builtin某些系统上,其中 bash 也是系统的sh)。

在该文档中:

test[使用基于参数数量的一组规则来评估条件表达式。

  • 0 个参数
    表达式为假。
  • 1 参数
    当且仅当参数不为空时,表达式才为真。
  • 2 个参数
    [...]
  • 3 个参数
    [...]

迂腐地说,当使用[而不是test命令时,最后的(必需的)]一个参数,但这不计入上面的数字(直接来自 bash 文档)。反正...

二参数规则是各种测试,三参数规则一般是比较。当您在 周围添加一个空格时=,您会得到三个参数。但当你把它们放在一起时,你会得到参数,如您所见,如果该参数不为 null,则返回 true。

好吧,从技术上讲,由于您忘记了参数扩展周围的引号[ $S1=$S2 ](以及其他地方),$S1并且$S2受到 split+glob 的影响,因此可能会导致更多参数传递给[命令。在 bash 中,就像在 ksh 中一样,这甚至会构成命令注入漏洞。

例如,如果$S1被定义为S1='-v xx[$(reboot)] -o yy'$S2as S2='zz',分割部分,默认值为$IFSyield -v, xx[$(reboot)], -o, yy=zz;[...]作为一个通配符,如果当前目录中有这样的文件,则xx[$(reboot)]可以扩展为,但如果没有,则将按原样传递到 ,并且在 bash 的内置函数中是一个测试,用于检查数组元素是否已设置,并且是否会扩展根据命令的输出来确定索引。xxoxxtxx[$(reboot)][-v array[index][$(reboot)reboot

正确的语法是[ "$S1" = "$S2" ],其中不要忘记引号也很重要。

答案2

在这种情况下,等于运算符不执行任何操作。

该表达式$S1=$S2计算为实际字符串,其中S1和的值就位S2,实际上是字符串文字foo=bar

由于该字符串文字不为空,因此语句

if [ "foo=bar" ];

计算结果为 true,并且执行 if 语句的主体。

相关内容