Answers:
这是周围的其他方法:=与==用于字符串比较,-eq是数字的。-eq在同一家庭-lt,-le,-gt,-ge,和-ne,如果这能帮助你记住哪个是哪个。
==顺便说一下,这是一种bash-ism。最好使用POSIX =。在bash中,这两个是等效的,而在纯sh =中,这是保证工作的唯一方法。
$ a=foo
$ [ "$a" = foo ]; echo "$?" # POSIX sh
0
$ [ "$a" == foo ]; echo "$?" # bash specific
0
$ [ "$a" -eq foo ]; echo "$?" # wrong
-bash: [: foo: integer expression expected
2
(附带说明:引用那些变量扩展!不要忽略上面的双引号。)
如果你正在写一个#!/bin/bash剧本,然后我建议使用[[代替。加倍的表单具有更多功能,更自然的语法和更少的陷阱,会让您绊倒。对于,不再需要在周围用双引号引起来$a:
$ [[ $a == foo ]]; echo "$?" # bash specific
0
也可以看看:
[[ $var = $pattern ]],如果你想要的东西,否则会被解释为一个的fnmatch模式,而不是被解释为一个字符串。该字符串foo没有非文字上的解释,从而使引号完全安全。仅当OP想要匹配时才需要foo*用foo引号或转义符(例如,星号为原义,不表示字符串后可能出现的任何内容)。
[[的无用扩展表示反对(表示这是您不给答案+1的唯一原因)。
[ ... ]和双等号==。:-/
这取决于操作员周围的测试构造。您可以选择双括号,双括号,单括号或测试
如果您使用((...)),您正在使用==C中的来测试算术净值:
$ (( 1==1 )); echo $?
0
$ (( 1==2 )); echo $?
1
(注意:在Unix上0表示平均值true,非零表示测试失败)
使用-eq双括号里面是一个语法错误。
如果您使用[...](或单括号)或[[...]](或双括号),或者test可以使用-eq,-ne,-lt,-le,-gt或-ge作为算术比较。
$ [ 1 -eq 1 ]; echo $?
0
$ [ 1 -eq 2 ]; echo $?
1
$ test 1 -eq 1; echo $?
0
的==单或双括号(或内部test命令)是一个字符串比较操作符:
$ [[ "abc" == "abc" ]]; echo $?
0
$ [[ "abc" == "ABC" ]]; echo $?
1
作为字符串运算符,=等效于==并注意其周围的空格=或其==要求。
虽然可以执行[[ 1 == 1 ]]或[[ $(( 1+1 )) == 2 ]]正在测试字符串相等性-而不是算术相等性。
因此,即使RH是一个字符串并且具有一个尾随空格,它也会-eq产生可能期望的整数值1+1等于的结果2:
$ [[ $(( 1+1 )) -eq "2 " ]]; echo $?
0
虽然相同的字符串比较占用了尾随空格,因此字符串比较失败:
$ [[ $(( 1+1 )) == "2 " ]]; echo $?
1
错误的字符串比较会产生完全错误的答案。在字典上, “ 10” 小于“ 2”,因此字符串比较返回true或0。这个错误让很多人咬了:
$ [[ 10 < 2 ]]; echo $?
0
相对于10的正确测试算术上小于2:
$ [[ 10 -lt 2 ]]; echo $?
1
在注释中,存在一个技术原因问题,-eq即对不相同的字符串在字符串上使用整数返回True:
$ [[ "yes" -eq "no" ]]; echo $?
0
原因是Bash未键入。在-eq使弦被解释为整数如果可能的话,包括基本转换:
$ [[ "0x10" -eq 16 ]]; echo $?
0
$ [[ "010" -eq 8 ]]; echo $?
0
$ [[ "100" -eq 100 ]]; echo $?
0
而0如果猛砸认为它只是一个字符串:
$ [[ "yes" -eq 0 ]]; echo $?
0
$ [[ "yes" -eq 1 ]]; echo $?
1
所以[[ "yes" -eq "no" ]]等于[[ 0 -eq 0 ]]
最后说明:测试构造的许多Bash特定扩展不是POSIX,因此在其他Shell中将失败。其他壳通常不支持[[...]]和((...))或==。
[[ "yes" -eq "no" ]]。bash如何将这些字符串强制转换为可以比较的整数值?;-)
==在代码示例中显示(非便携式),并且仅=在下面提及(便携式,标准化)。
==是bash的特定别名=,它执行字符串(词法)比较,而不是数字比较。eq当然是数值比较。
最后,我通常更喜欢使用表格 if [ "$a" == "$b" ]
==此处使用的格式不正确,仅=由POSIX指定。
==则将其放在[[和之间]]。(并确保脚本的第一行指定使用/bin/bash。)
伙计们:几个答案显示了危险的例子。OP的示例[ $a == $b ]专门使用了无引号的变量替换(截至17年10月编辑)。因为[...]这样对于字符串相等是安全的。
但是,如果要枚举诸如之类的替代项[[...]],则还必须告知必须在右侧加引号。如果未引用,则为模式匹配!(来自bash手册页:“可以引用模式的任何部分以强制将其匹配为字符串。”)。
在bash中,两个产生“ yes”的语句是模式匹配,其他三个是字符串相等:
$ rht="A*"
$ lft="AB"
$ [ $lft = $rht ] && echo yes
$ [ $lft == $rht ] && echo yes
$ [[ $lft = $rht ]] && echo yes
yes
$ [[ $lft == $rht ]] && echo yes
yes
$ [[ $lft == "$rht" ]] && echo yes
$
[ "$lht" = "$rht" ] 与引号保持一致。如果您有创建的文件touch 'Afoo -o AB',[ $lft = $rht ]将返回true,即使该文件的名称是不是在所有相同AB。
[[总体而言是bash(以及许多其他外壳)采用的1980年代的ksh-ism。这是整点-如果你有[[在所有的,那么你可以安全地假定所有分机KSH周围(实现fnmatch()风格的模式匹配,与ERE正则表达式=~,是的,串分裂的抑制和文件系统通配)会可用。由于[[全部是非POSIX语法,因此假设它所具有的功能将可用就不会造成额外的可移植性损失。