为什么[[-eq]]在Bash中将非数字字符串显示为相等? [英] Why does [[ -eq ]] show non-numerical strings as equal in Bash?

查看:43
本文介绍了为什么[[-eq]]在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆