我知道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)。
答案 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 属性即可在表达式中使用。