Ist „test“ oder „[“ oder „[[“ sowohl zwischen Bash-Shells als auch zwischen anderen Shells portabler?

Ist „test“ oder „[“ oder „[[“ sowohl zwischen Bash-Shells als auch zwischen anderen Shells portabler?

Ich sehe, ich kann

$ [ -w /home/durrantm ] && echo "writable"
writable

oder

$ test -w /home/durrantm && echo "writable"
writable

oder

$ [[ -w /home/durrantm ]] && echo "writable"
writable

Ich verwende gern die dritte Syntax. Sind sie in jeder Hinsicht und für alle negativen und Randfälle gleichwertig? Gibt es Unterschiede in der Portabilität, z. B. zwischen Bash unter Ubuntu und unter OS X oder älteren/neueren Bash-Versionen, z. B. vor/nach 4.0, und erweitern beide Ausdrücke auf die gleiche Weise?

Antwort1

Ja, es gibt Unterschiede. Die portabelsten sind testoder [ ]. Diese sind beide Teil derPOSIX- testSpezifikation.

Das if ... fiKonstrukt ist auchdefiniert durch POSIXund sollte vollständig portierbar sein.

Dies [[ ]]ist eine kshFunktion, die auch in einigen Versionen von bash(alle modernen), in zshund vielleicht in anderen, ist aber nicht vorhanden in shoder dashoder den verschiedenen anderen einfacheren Schalen.

Um Ihre Skripte portierbar zu machen, verwenden Sie [ ]oder .testif ... fi

Antwort2

[ist Synonym für den testBefehl und gleichzeitig einBash integriertund separater Befehl. Aber [[ist einBash-Schlüsselwortund funktioniert nur in einigen Versionen. Aus Gründen der Portabilität ist es daher besser, einzelne []odertest

[ -w "/home/durrantm" ] && echo "writable"

Antwort3

Bitte beachten Sie, dass dies [] && cmdnicht dasselbe ist wie if .. fiBauen.

Manchmal ist das Verhalten ziemlich ähnlich und Sie können [] && cmdanstelle von verwenden if .. fi. Aber nur manchmal. Wenn Sie mehr als einen Befehl ausführen müssen, wenn die Bedingung oder Sie müssen, if .. else .. fiseien Sie vorsichtig und achten Sie auf die Logik.

Ein paar Beispiele:

[ -z "$VAR" ] && ls file || echo wiiii

Ist nicht dasselbe wie

if [ -z $VAR ] ; then
  ls file
else
  echo wiii
fi

denn wenn lses fehlschlägt, echowird es ausgeführt, was mit nicht passieren wird if.

Ein anderes Beispiel:

[ -z "$VAR" ] && ls file && echo wiii

ist nicht dasselbe wie

if [ -z "$VAR" ] ; then
   ls file
   echo $wiii
fi

obwohl diese Konstruktion die gleiche Wirkung hat

[ -z "$VAR" ] && { ls file ; echo wiii ; }

Bitte beachten Sie ;, dass das Echo wichtig ist und vorhanden sein muss.

Zusammenfassend können wir also sagen:

[] && cmd== Wenn der erste Befehl erfolgreich ist, führen Sie den nächsten aus

if .. fi== wenn Bedingung (kann auch der Testbefehl sein) dann führe Befehl(e) aus

Also nur für die Portabilität zwischen [und [[die Verwendung [.

ifist POSIX-kompatibel. Wenn Sie also zwischen beiden wählen müssen, [berücksichtigen ifSie Ihre Aufgabe und das erwartete Verhalten.

Antwort4

Verwenden Sie aus Portabilitätsgründen test/ [. Wenn Sie die Portabilität jedoch nicht benötigen, verwenden Sie zum Schutz Ihrer eigenen geistigen Gesundheit und der anderer, die Ihr Skript lesen [[, . :)

Siehe auch What is the difference between test, [ and [[ ?imBashFAQ.

verwandte Informationen