测试语句中 bash 中的字符串和数字比较?

测试语句中 bash 中的字符串和数字比较?

我不确定我正在做的比较:

   if [ "$exit_status" -eq 0 ];then
   #some statements
   fi

这种比较数字或引号的正确方法是否使变量exit_status成为与 0 比较的字符串。我不知道这在某些情况下是否会失败。

答案1

是的,这是正确的。

shell 中的引号与其他语言中的引号有着不同的用途。看这个答案更多细节。

在 shell 中,引号用于防止 shell 特殊处理某些字符,并防止 shell 对某些类型的扩展执行某些操作(例如本例中的变量扩展)。

通常,在这种情况下,您希望"$exit_status"扩展到[命令的一个参数,即该变量的内容,因此您需要引号。

答案2

[ "$exit_status" -eq 0 ]如果 $exit_status 仅包含数字,则正确,并且您也可以删除引号(只要 IFS 不包含数字)。

如果 x 为空或未设置,[ "$x" -eq 6 ]则会导致错误,但[[ "$x" -eq 6 ]]不会:

$ x=; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ unset x; [ "$x" -eq 6 ]
-bash: [: : integer expression expected
$ x=; [[ "$x" -eq 6 ]]
$ unset x; [[ "$x" -eq 6 ]]
$ 

算术运算符去除空格:

$ [ '6 ' -eq $'\n\t6' ]; echo $?
0

在 [[ 内部,算术运算符的操作数是算术表达式,因此 example[[ 4 -eq 2+2 ]]为 true。以 0 开头的数字被视为八进制数:

$ [[ 010 -eq 8 ]]; echo $?
0
$ [ 010 -eq 8 ]; echo $?
1

我什至经常使用 = / == 来比较整数。 = 和 == 在 bash 中的 [[ 和 [ 中是等价的。 == 和 [[ 不是由 POSIX 定义的。

[[ 内部不执行分词和路径名扩展。[[ $x = $y ]]将 y 视为模式,但[[ $x = "$y" ]]按字面意思对待 y:

$ x=44; y='4*'
$ [[ $x = $y ]]; echo $?
0
$ [[ $x = "$y" ]]; echo $?
1

答案3

但引用数字并没有多大用处。如果参数值是数字,那么引号不会改变任何内容,如果不是,那么 if 无论如何都会失败。好吧,并非在所有情况下:

exit_status="a = a -o 0"; [ "$exit_status" -eq 0 ] # returns false
exit_status="a = a -o 0"; [ $exit_status -eq 0 ] # returns true

这是因为[它是 bash 内置命令,但仍然是一个简单命令,而[[是一个更改命令行解析的复合命令。

相关内容