除了修饰/偏好参数之外,原因之一可能是[ ! "$a" = "$b" ]
与相比,在极端情况下失败的实现更多[ "$a" != "$b" ]
。
如果实现遵循POSIX算法,则两种情况都应该是安全的,但是即使在今天(截至撰写本文的2018年初),仍然有一些实现失败的情况。例如,使用a='(' b=')'
:
$ (a='(' b=')'; busybox test "$a" != "$b"; echo "$?")
0
$ (a='(' b=')'; busybox test ! "$a" = "$b"; echo "$?")
1
对于dash
0.5.9之前的版本,例如sh
在Ubuntu 16.04上找到的0.5.8 :
$ a='(' b=')' dash -c '[ "$a" != "$b" ]; echo "$?"'
0
$ a='(' b=')' dash -c '[ ! "$a" = "$b" ]; echo "$?"'
1
(已在0.5.9中修复,请参见https://www.mail-archive.com/dash@vger.kernel.org/msg00911.html)
这些实现被[ ! "(" = ")" ]
视为 [ ! "(" "text" ")" ]
是[ ! "text" ]
(测试“文本”是否为空字符串),而POSIX则将其视为[ ! "x" = "y" ]
(测试“ x”和“ y”是否相等)。这些实现失败,因为在这种情况下它们执行了错误的测试。
请注意,还有另一种形式:
! [ "$a" = "$b" ]
那需要一个POSIX外壳(不适用于旧的Bourne外壳)。
请注意,几个实现也存在[ "$a" = "$b" ]
(和[ "$a" != "$b" ]
)问题,并且仍然像Solaris 10上的[
内置功能一样/bin/sh
(Bourne shell,POSIX shell在中/usr/xpg4/bin/sh
)。这就是为什么您看到类似以下内容的原因:
[ "x$a" != "x$b" ]
在试图移植到旧系统的脚本中。
!(x==y)
从(!x)==y
。