不等于的语法重要吗?

不等于的语法重要吗?

在编写脚本时,我通常使用以下语法编写 if,因为这样我更容易理解接下来发生的事情是不正确的。

if [ ! "$1" = "$2" ]; then

还有人说下面的方式比较好

if [ "$1" != "$2" ]; then

问题是,当我问为什么以及是否存在任何差异时,似乎没有人给出任何答案。

那么,这两种语法有什么区别吗?其中一个比另一个更安全吗?或者这只是一个偏好/习惯的问题?

答案1

除了装饰/偏好参数之外,原因之一可能是[ ! "$a" = "$b" ]在极端情况下失败的实现比[ "$a" != "$b" ].

如果实施遵循,这两种情况都应该是安全的POSIX 算法,但即使在今天(截至撰写本文时为 2018 年初),仍然存在失败的实现。例如,与a='(' b=')'

$ (a='(' b=')'; busybox test "$a" != "$b"; echo "$?")
0
$ (a='(' b=')'; busybox test ! "$a" = "$b"; echo "$?")
1

对于0.5.9 之前的版本,例如 Ubuntu 16.04 上的dash0.5.8 :sh

$ a='(' b=')' dash -c '[ "$a" != "$b" ]; echo "$?"'
0
$ a='(' b=')' dash -c '[ ! "$a" = "$b" ]; echo "$?"'
1

(0.5.9 中已修复,请参阅https://www.mail-archive.com/[电子邮件受保护]/msg00911.html

这些实现就这样对待[ ! "(" = ")" ][ ! "(" "text" ")" ]测试[ ! "text" ]“text”是否为空字符串),而 POSIX 强制要求如此[ ! "x" = "y" ](测试“x”和“y”是否相等)。这些实现失败是因为它们在这种情况下执行了错误的测试。

请注意,还有另一种形式:

! [ "$a" = "$b" ]

那个需要一个 POSIX shell(不能与旧的 Bourne shell 一起使用)。

注意一些实现也遇到了[ "$a" = "$b" ]( 和) 的问题[ "$a" != "$b" ]并且仍然像Solaris 10 上[的内置一样/bin/sh(Bourne shell,POSIX shell 位于 中/usr/xpg4/bin/sh)。这就是为什么你会看到这样的东西:

[ "x$a" != "x$b" ]

在试图移植到旧系统的脚本中。

答案2

语法x != y更好,因为! x == y容易出错 - 需要了解不同语言的运算符优先级。语法! x == y可以解释为!(x == y)or (!x) == y,具体取决于!vs的优先级=


例如,在c++否定中! 出现在比较/关系运算符之前 ==,因此有以下代码:

#include<iostream>

using namespace std;

int main()
{
  int x=1, y=2;
  if(     x  != y   ) cout<<"true"<<endl; else cout<<"false"<<endl;
  if(  !  x  == y   ) cout<<"true"<<endl; else cout<<"false"<<endl;
  if(  !( x  == y ) ) cout<<"true"<<endl; else cout<<"false"<<endl;
  if(   (!x) == y   ) cout<<"true"<<endl; else cout<<"false"<<endl;
}

回报

true
false
true
false

在许多其他语言中也可以观察到类似的行为,包括awkUnix 世界中常用的工具。


另一方面,x != y作为一种行之有效的模式,将运营商聚集在一起不会导致任何混乱。此外,从技术上讲, !=通常不是两个,而是一个运算符,因此评估速度应该比单独比较然后求反要快一些。因此,虽然这两种语法都可以在 bash 中使用,但我建议遵循,x != y因为遵循某些标准逻辑的代码更容易阅读和维护。

答案3

这种事情是非常基于观点,因为“答案”很大程度上取决于个人大脑的连接方式。虽然在语义上确实NOT ( A == B )与 相同(A != B ),但一个人可能更清楚,而另一个人可能更清楚。它也依赖于上下文。例如,如果我设置了一个标志,则使用一种语法比另一种语法的含义可能更清晰:

if NOT ( fileHandleStatus == FS_OPEN )

相对于

if ( fileHandleStatus != FS_OPEN )

相关内容