为什么[[-eq]]在Bash中将非数字字符串显示为相等? [英] Why does [[ -eq ]] show non-numerical strings as equal in Bash?
问题描述
我知道我们应该使用 =
(或其别名 ==
)来比较Bash中的字符串.但是我忘记了它,并在脚本中使用了 -eq
,得到了奇怪的结果,但是没有错误.
我还没有找到与此有关的任何文档,但是从我的测试中, [["$ foo" -eq"$ bar"]]
似乎总是对 进行评估 0
,即成功,对于 $ foo
或 $ bar
的任何值,只要它们不以一个数字:
$ [[" 1 -eq"1"]]&&回声是||回声不是的$ [[" 1 -eq"0"]]&&回声是||回声不不$ [["x1" -eq"0"]]&&回声是||回声不是的$ [["x1" -eq"x0"]]&&回声是||回声不是的$ [[foo -eq bar]]&&回声是||回声不是的$ [[so -eq different]]&&回声是||回声不是的
当一个值以数字开头时,它的计算结果为 1
(错误):
$ [[1x -eq 1]]&&回声是||回声不bash:[[:1x:Valeur trop Grande pour la base(符号为erronéest"1x")不
我收到的错误消息是法语,表示"对于基数而言值太高(错误符号是"1x" ".
为什么在获取非数字时不返回 1
和/或显示错误?当您犯了这个错误时,这使得事情真的很难调试.
我使用的是GNU bash版本4.3.11(1)-发行版(x86_64-pc-linux-gnu).
在算术上下文中,bash会首先尝试查看它是否为数字,然后再查看其是否为有效的var名称.如果是var名称,但var为空或未定义,则该值为0.
[STEP 100]#echo $ BASH_VERSION4.4.12(1)-发布[STEP 101]#n = 123[步骤102]#[[n -eq 123]]&&回声是||回声不是的[步骤103]#[['n'-eq 123]]&&回声是||回声不是的[STEP 104]#varname = n[STEP 105]#[[$ varname -eq 123]]&&回声是||回声不是的[STEP 106]#[[notdefined -eq 123]]&&回声是||回声不不[STEP 107]#[[notdefined -eq 0]]&&回声是||回声不是的[STEP 108]#
即使这样可行:
[STEP 108]#expr ='100 + 20 + 3'[STEP 109]#[[expr -eq 123]]&&回声是||回声不是的[STEP 110]#
扩展是递归的:
[STEP 201]#a = b[STEP 202]#b = c[STEP 203]#c = 123[STEP 204]#[[a -eq 123]]&&回声是||回声不是的[STEP 205]#((a == 123))&&回声是||回声不是的[STEP 206]#
在bash的手册页中:
算术评估
允许将Shell变量用作操作数;在对表达式求值之前执行参数扩展.在表达式中, shell变量也可以按名称引用,而无需使用参数扩展语法.如果使用名称引用而不使用参数扩展语法,则null或未设置的shell变量的值为0.引用变量时,或使用
declare -i 赋予 integer 属性的变量时,变量的值将作为算术表达式求值.为code>分配了一个值.空值的计算结果为0.shell变量无需打开其 integer 属性即可在表达式中使用.
I know we should use =
(or its alias ==
) to compare strings in Bash. But I forgot about it and used -eq
in a script, getting strange results, but no error.
I haven’t found any documentation regarding this but from my tests, [[ "$foo" -eq "$bar" ]]
appears to always evaluate to 0
, i.e. success, for any value of $foo
or $bar
, provided they don’t start with a digit:
$ [[ "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
It does evaluate to 1
(error) when one value starts with a digit:
$ [[ 1x -eq 1 ]] && echo yes || echo nope
bash: [[: 1x : valeur trop grande pour la base (le symbole erroné est "1x")
nope
The error message I get is French for "value too high for the base (the erroneous symbol is "1x"".
Why doesn’t it return 1
and/or show an error when getting a non-number? It makes things really hard to debug when you made that mistake.
I used GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu).
In arithmetic context bash would try first to see if it's a number and then would see if it's a valid var name. If it's a var name but the var is empty or not defined then the value will be 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] #
Even this works:
[STEP 108] # expr='100 + 20 + 3'
[STEP 109] # [[ expr -eq 123 ]] && echo yes || echo no
yes
[STEP 110] #
And the expansion is recursive:
[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] #
From bash's man page:
ARITHMETIC EVALUATION
Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated. Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax. A shell variable that is null or unset evaluates to 0 when referenced by name without using the parameter expansion syntax. The value of a variable is evaluated as an arithmetic expression when it is referenced, or when a variable which has been given the integer attribute using
declare -i
is assigned a value. A null value evaluates to 0. A shell variable need not have its integer attribute turned on to be used in an expression.
这篇关于为什么[[-eq]]在Bash中将非数字字符串显示为相等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!