Um auf Chepners aufschlussreichem Kommentar zu dieser Frage aufzubauen:
-
In
[ ! condition ], die!ist nur ein Argument bis[eingebaut (ein effektiver Alias destesteingebaut); es passiert also, dass[/testinterpretiert Argument!als Verneinung. -
In
! [ condition ], die!ist ein Shell-Schlüsselwort das negiert jeden Befehl, der ihm folgt (was zufällig[ist in diesem Fall).
Eine Sache, die ! [ condition ] Syntax gibt Ihnen implizit, dass die Negation für alles [ condition ] gilt wertet als Ganzes aus , also wenn das die Absicht ist, brauchen Sie sich keine Gedanken über die Operatorpriorität zu machen.
Leistungsmäßig , welche Syntax Sie wählen, macht wahrscheinlich keinen großen Unterschied; Schnelltests empfehlen:
-
Wenn
conditionist in beiden Fällen buchstäblich gleich, wobei der!übergeben wird als Argument für[ist unwesentlich schneller. -
Wenn
!wird als Schlüsselwort verwendet , und Sie können daher die Bedingung vereinfachen, indem Sie sich keine Gedanken über den Vorrang machen, kann es etwas schneller sein (z. B.! [ 0 -o 1 ]vs.[ ! \( 0 -o 1 \) ]; Beachten Sie, dass die POSIX-Spezifikation. rät von der Verwendung von-aab und-owegen Unklarheit).
Das heißt, wenn wir über Bash sprechen , dann sollten Sie erwägen, [[ zu verwenden statt [ , weil [[ ist ein Shell-Schlüsselwort das den eingeschlossenen Ausdruck in einem speziellen Kontext analysiert, der:
- bietet mehr Funktionen
- ermöglicht es Ihnen, Ausdrücke sicher mit
&&zu kombinieren und|| - kommt mit weniger Überraschungen
- ist auch etwas schneller (obwohl das in der Praxis selten eine Rolle spielt)
Siehe diese Antwort von mir.
! negiert den Exit-Code des folgenden Befehls:
$ ! test 1 = 1 || echo $? # negate command with true expression
1
Wie in der Manpage gesagt, test (und ähnlich [ builtin) beenden Sie mit dem Status, der durch den folgenden Ausdruck bestimmt wird:
$ test ! 1 = 1 || echo $? # return false expression
1
$ [ ! 1 = 1 ] || echo $?
1
Für einen gegebenen Ausdruck :
- auf der einen Seite negierst du den
testBefehl, der mit dem wahren Ausdrucksstatus beendet wird. - auf der anderen Seite negierst du einen Ausdruck und den
testBefehl (oder[) mit falschem Status beenden
Beide haben den gleichen Effekt.
Ich würde also sagen, dass diese Syntax äquivalent ist. Mit dem Vorteil für externe ! um zusammengesetzte Tests zu negieren :
$ ! [ 1 = 1 -a 2 = 2 ] || echo $?
1