为什么[[-eq]]在Bash中显示非数字字符串相等?

时间:2017-11-24 14:37:54

标签: bash

我知道we should use =(或其别名==)来比较Bash中的字符串。但我忘记了它,并在脚本中使用-eq,得到了奇怪的结果,但没有错误。

我没有找到任何有关此问题的文档,但是从我的测试中,[[ "$foo" -eq "$bar" ]]似乎始终评估为0,即成功,任何 $foo$bar的值,前提是它们不以数字开头:

$ [[ "1" -eq "1" ]] && echo yes || echo nope
yes
$ [[ "1" -eq "0" ]] && echo yes || echo nope
nope
$ [[ "x1" -eq "0" ]] && echo yes || echo nope
yes
$ [[ "x1" -eq "x0" ]] && echo yes || echo nope
yes
$ [[ foo -eq bar ]] && echo yes || echo nope
yes
$ [[ so -eq different ]] && echo yes || echo nope
yes

当一个值以数字开头时,它会评估为1(错误):

$ [[ 1x -eq 1 ]] && echo yes || echo nope
bash: [[: 1x : valeur trop grande pour la base (le symbole erroné est "1x")
nope

我得到的错误信息是法语" 值对于基数来说太高(错误的符号是" 1x" "。

为什么在获取非号码时它不会返回1和/或显示错误?当你犯这个错误时,它会使调试变得非常困难。

我使用GNU bash,版本4.3.11(1)-release(x86_64-pc-linux-gnu)。

1 个答案:

答案 0 :(得分:4)

在算术上下文中,bash会首先尝试查看它是否为数字,然后查看它是否为有效的var名称。如果它是一个var名称,但var为空或未定义,那么该值将为0.

[STEP 100] # echo $BASH_VERSION
4.4.12(1)-release
[STEP 101] # n=123
[STEP 102] # [[ n -eq 123 ]] && echo yes || echo no
yes
[STEP 103] # [[ 'n' -eq 123 ]] && echo yes || echo no
yes
[STEP 104] # varname=n
[STEP 105] # [[ $varname -eq 123 ]] && echo yes || echo no
yes
[STEP 106] # [[ notdefined -eq 123 ]] && echo yes || echo no
no
[STEP 107] # [[ notdefined -eq 0 ]] && echo yes || echo no
yes
[STEP 108] #

即便如此:

[STEP 108] # expr='100 + 20 + 3'
[STEP 109] # [[ expr -eq 123 ]] && echo yes || echo no
yes
[STEP 110] #

扩展是递归的:

[STEP 201] # a=b
[STEP 202] # b=c
[STEP 203] # c=123
[STEP 204] # [[ a -eq 123 ]] && echo yes || echo no
yes
[STEP 205] # (( a == 123 )) && echo yes || echo no
yes
[STEP 206] #

来自bash的手册页:

  

ARITHMETIC EVALUATION

     

允许Shell变量作为操作数;在计算表达式之前执行参数扩展。在表达式中, shell变量也可以通过名称引用,而不使用参数扩展语法。在不使用参数扩展语法的情况下按名称引用时,null或unset的shell变量的计算结果为0。 变量的值在被引用时被计算为算术表达式,或者当使用declare -i赋予整数属性的变量被赋值时值。 null值的计算结果为0. shell变量不需要打开其 integer 属性即可在表达式中使用。