it-swarm.com.de

Ist die Syntax nicht gleich Materie?

Beim Schreiben von Skripten schreibe ich meine ifs normalerweise mit der folgenden Syntax, da ich leichter verstehen kann, dass das, was als nächstes kommt, nicht wahr ist.

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

Andere sagen, dass der Weg unten besser ist

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

Die Sache ist, wenn ich frage, warum und ob es irgendwelche Unterschiede gibt, scheint niemand eine Antwort zu haben.

Gibt es also Unterschiede zwischen den beiden Syntaxen? Ist einer von ihnen sicherer als der andere? Oder ist es nur eine Frage der Präferenz/Gewohnheit?

22
Jimmy_A

Neben den Kosmetik-/Präferenzargumenten könnte ein Grund sein, dass es mehr Implementierungen gibt, bei denen [ ! "$a" = "$b" ] In Eckfällen fehlschlägt als bei [ "$a" != "$b" ].

Beide Fälle sollten sicher sein, wenn Implementierungen folgen der POSIX-Algorithmus , aber auch heute (Anfang 2018 zum Zeitpunkt des Schreibens) gibt es noch Implementierungen, die fehlschlagen. Zum Beispiel mit a='(' b=')':

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

Mit dash Versionen vor 0.5.9, wie der 0.5.8, die unter Ubuntu 16.04 als sh gefunden wurde, zum Beispiel:

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

(behoben in 0.5.9, siehe https://www.mail-archive.com/[email protected]/msg00911.html )

Diese Implementierungen behandeln [ ! "(" = ")" ] als [ ! "(" "text" ")" ], dh [ ! "text" ] (Testen Sie, ob "text" die Nullzeichenfolge ist), während POSIX vorschreibt, dass [ ! "x" = "y" ] ( Test "x" und "y" auf Gleichheit). Diese Implementierungen schlagen fehl, weil sie in diesem Fall den falschen Test durchführen.

Beachten Sie, dass es noch eine andere Form gibt:

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

Dafür ist eine POSIX-Shell erforderlich (funktioniert nicht mit der alten Bourne-Shell).

Beachten Sie, dass einige Implementierungen hatten auch Probleme mit [ "$a" = "$b" ] (Und [ "$a" != "$b" ]) und immer noch das [, Das in /bin/sh unter Solaris 10 (eine Bourne-Shell, wobei sich die POSIX-Shell in /usr/xpg4/bin/sh befindet). Deshalb sehen Sie Dinge wie:

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

In Skripten, die versuchen, auf alte Systeme portierbar zu sein.

35

Die Syntax x != y Ist besser, da ! x == y Fehleranfällig ist - erfordert Kenntnisse über die Vorrangstellung der Operatoren, die von Sprache zu Sprache unterschiedlich ist. Die Syntax ! x == y Könnte je nach Priorität von (!x) == y Gegenüber ! Als !(x == y) oder = Interpretiert werden.


Zum Beispiel in c++ Negation !kommt vor dem Vergleichs-/Vergleichsoperator==, Daher der folgende Code:

#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;
}

kehrt zurück

true
false
true
false

Ein ähnliches Verhalten kann in vielen anderen Sprachen beobachtet werden, einschließlich z. awk - ein in der Unix-Welt häufig verwendetes Tool.


Das Zusammenführen von Operatoren über x != y Führt jedoch nicht zu Verwirrung als etabliertes Muster. Darüber hinaus ist != Technisch gesehen sehr oft nicht zwei, sondern nur ein Operator, weshalb die Auswertung sogar geringfügig schneller sein sollte als ein separater Vergleich und dann eine Negation. Obwohl beide Syntaxen in bash funktionieren, würde ich empfehlen, x != y Zu folgen, da es viel einfacher ist, Code zu lesen und zu pflegen, der einer Standardlogik folgt.

8
jimmij

Diese Art von Dingen ist sehr meinungsbasiert, da die "Antwort" sehr stark davon abhängt, wie das Gehirn eines Individuums verdrahtet ist. Während es wahr ist, dass NOT ( A == B ) semantisch identisch mit (A != B ) Ist, könnte eines für eine Person klarer und das andere für eine andere Person klarer sein. Es ist auch kontextabhängig. Wenn ich beispielsweise ein Flag gesetzt habe, sind die Bedeutungen mit einer Syntax gegenüber einer anderen klarer:

if NOT ( fileHandleStatus == FS_OPEN )

im Gegensatz zu

if ( fileHandleStatus != FS_OPEN )
4
DopeGhoti