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语法,因此假设它所具有的功能将可用就不会造成额外的可移植性损失。