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 sicherer als der andere? Oder ist es nur eine Frage der Präferenz / Gewohnheit?
!(x==y)
von diesen unterscheiden zu können(!x)==y
.if [ ! "$string" = "one" ]
zu übersetzen , wenn nicht der Wert von$string
Gleichenone
. Und das heißtif [ "$string" != "one"]
, wenn der Wert von$string
nicht gleich istone
?!=
Syntax) ist nur offensichtlicher.Antworten:
Neben den kosmetischen / Präferenz-Argumenten könnte ein Grund sein, dass es mehr Implementierungen gibt, bei denen
[ ! "$a" = "$b" ]
in Eckfällen Fehler auftreten als bei[ "$a" != "$b" ]
.Beide Fälle sollten sicher sein, wenn Implementierungen dem POSIX-Algorithmus folgen , aber selbst heute (Anfang 2018, wie zum Zeitpunkt des Schreibens) gibt es noch Implementierungen, die fehlschlagen. Zum Beispiel mit
a='(' b=')'
:Mit
dash
Versionen vor 0.5.9, wie zum Beispiel der Version 0.5.8sh
auf Ubuntu 16.04:(behoben in 0.5.9, siehe https://www.mail-archive.com/[email protected]/msg00911.html )
Diese Implementierungen behandeln
[ ! "(" = ")" ]
wie[ ! "(" "text" ")" ]
das ist[ ! "text" ]
(Test , ob „text“ ist der Null - String) , während POSIX Mandate es zu sein[ ! "x" = "y" ]
(Test „x“ und „y“ für die Gleichstellung). Diese Implementierungen schlagen fehl, weil sie in diesem Fall den falschen Test durchführen.Beachten Sie, dass es noch ein anderes Formular gibt:
Dieser benötigt eine POSIX-Shell (funktioniert nicht mit der alten Bourne-Shell).
Beachten Sie, dass einige Implementierungen ebenfalls Probleme mit
[ "$a" = "$b" ]
(und[ "$a" != "$b" ]
) hatten und immer noch mit dem in Solaris 10 integrierten[
Betriebssystem/bin/sh
(einer Bourne-Shell, in der sich die POSIX-Shell befindet/usr/xpg4/bin/sh
) übereinstimmen . Deshalb sehen Sie Dinge wie:In Skripten, die versuchen, auf alte Systeme portierbar zu sein.
quelle
! "$a" = "b"
Sie müssen vorsichtiger sein, wie Sie sie schreiben, um den Vergleich festzulegen. Aus Ihrem Beispiel geht hervor, dass der zweite Befehlnot zero
nützlich oder beunruhigend sein kann. Es kann nützlich sein, wenn Sie[ ! "$a" = "$b" ]
scheitern nur wenn$a
ist(
und$b
ist)
, sie behauptet , dass sie identisch sind , wenn sie es nicht sind ,(
ist nicht die gleiche Zeichenfolge wie)
, aber[
führt die falsche Test in diesem Fall.[ ! "$a" = "$b" ]
läuft dies auf Folgendes hinaus: Wird in Buggy-Shell-Implementierungen manchmal falsch gehandhabt (was meiner Meinung nach mehr oder weniger den ersten Satz der Antwort wiedergibt).Die
x != y
Syntax ist besser, weil sie! x == y
fehleranfällig ist - erfordert Kenntnisse über die Rangfolge der Operatoren, die von Sprache zu Sprache unterschiedlich sind. Die Syntax kann je nach Priorität von vs! x == y
als!(x == y)
oder interpretiert werden .(!x) == y
!
=
Zum Beispiel kommt in der
c++
Negation!
der Vergleichsoperator / Vergleichsoperator vor==
, daher der folgende Code:kehrt zurück
Ein ähnliches Verhalten kann in vielen anderen Sprachen beobachtet werden, einschließlich z. B.
awk
- einem in der Unix-Welt häufig verwendeten Tool.Auf der anderen Seite führt das Sammeln von Operatoren über
x != y
keine Verwirrung als ein gut etabliertes Muster. Im Übrigen sind es technisch gesehen!=
oft nicht zwei, sondern nur ein Operator, weshalb die Auswertung geringfügig schneller sein sollte als der separate Vergleich und die anschließende Verneinung. Daher würde ich empfehlen, obwohl beide Syntaxen in bash funktionieren, zu folgen,x != y
da es viel einfacher ist, Code zu lesen und zu warten, der einer Standardlogik folgt.quelle
Diese Art von Dingen ist sehr meinungsbasiert, da die "Antwort" sehr stark davon abhängt, wie das Gehirn eines Individuums verdrahtet ist. Zwar stimmt das semantisch,
NOT ( A == B )
ist aber identisch mit(A != B )
, könnte einer für eine Person klarer sein und der andere für eine andere. Es ist auch kontextabhängig. Wenn ich zum Beispiel ein Flag gesetzt habe, sind die Bedeutungen bei einer Syntax klarer als bei einer anderen:im Gegensatz zu
quelle
if ( FS_OPEN != fileHandleStatus )
als Ergebnis der Leichtigkeit des versehentlichen Tippens=
statt==
in Sprachen, in denen das erstere Aufgabe ist und der spätere Gleichheitstest (wie C) ...