出于好奇,在进行 bash 变量比较(其值为 an integer
)时,可以针对某些声明为 anint
或 as 的预定义值对其进行测试string
。
示例脚本:
#!/bin/bash
f1()
{
[ "$1" == "1" ] && echo "$FUNCNAME: \"1\" compared as string"
}
f2()
{
[[ "$1" -eq 1 ]] && echo "$FUNCNAME: \"1\" compared as int"
}
f1 $1
f2 $1
Run Code Online (Sandbox Code Playgroud)
输出:
$ ./param.sh 1
f1: "1" compared as string
f2: "1" compared as int
Run Code Online (Sandbox Code Playgroud)
和
$ ./param.sh blah
$
Run Code Online (Sandbox Code Playgroud)
这两个函数的行为方式相同,所以我想知道检查整数变量时是否有首选方法?我会去检查int
vsint
因为它更严格,但我想知道这样做是否有任何缺点string
?
在这种情况下,f2()
对比较也更加严格,即传递一个十进制值会破坏它,而不f1()
会有问题。
god*_*eek 20
是的,很多不同。例如,=
检查字符串是否完全相等,但-eq
在检查相等之前对两个表达式进行算术计算:
$ [ " 1 " -eq 1 ] && echo equal || echo not
equal
$ [ " 1 " = 1 ] && echo equal || echo not
not
$ [ +1 -eq 1 ] && echo equal || echo not
equal
$ [ +1 = 1 ] && echo equal || echo not
not
$ [ "0+1" -eq 1 ] && echo equal || echo not
equal
$ [ "0+1" = 1 ] && echo equal || echo not
not
Run Code Online (Sandbox Code Playgroud)
此外,空字符串恰好在数字上等于零:
$ [ "" -eq 0 ] && echo equal || echo not
equal
$ [ "" = 0 ] && echo equal || echo not
not
Run Code Online (Sandbox Code Playgroud)
当您引入比较运算符时,会出现另一类差异 - 考虑<
vs -lt
,例如:
$ [[ 2 -lt 10 ]] && echo less || echo not
less
$ [[ 2 < 10 ]] && echo less || echo not
not
Run Code Online (Sandbox Code Playgroud)
这是因为字符串“2”按字母顺序在字符串“10”之后(因为 1 在 2 之前),但数字“2”在数字上小于数字“10”。
当您比较大于或小于时,整数与字符串比较变得最重要:
#!/bin/bash
eleven=11
nine=9
[[ $nine < $eleven ]] && echo string # fail
[[ "$nine" -lt "$eleven" ]] && echo integer # pass
Run Code Online (Sandbox Code Playgroud)
第一个失败,因为按字典顺序排序时 9 在 11 之后。
请注意,使用引号并不能确定您是在比较字符串还是数字,而是由运算符决定。您可以添加或删除上面的引号,它没有任何区别。Bash 在双括号内捕获未定义的变量,因此不需要引号。使用带单括号的引号进行数值测试不会节省您的费用,因为:
[ "" -lt 11 ]
Run Code Online (Sandbox Code Playgroud)
无论如何都是错误(“需要整数表达式”)。引号是单括号中字符串比较的有效保护措施:
[ "" \< 11 ]
Run Code Online (Sandbox Code Playgroud)
注意在双括号内,""
will-eq 0
但不是== 0
。