Was in einem Bash-Skript idiomatischer ist: `|| true` oder `|| : `?

36

Ich mache nicht sonderlich viel Shell-Scripting, deshalb war ich ein wenig überrascht, als ich die Dokumentation fürgit submodule las und die Syntax sah, die sie in dieser Dokumentation verwendeten:

Eine Rückgabe ungleich Null vom Befehl in einem Submodul führt zum Abbruch der Verarbeitung. Dies kann durch Hinzufügen || :am Ende des Befehls überschrieben werden .

Ich musste nachschlagen, || :um einen Befehl zum erfolgreichen Beenden zu zwingen. Jedes Mal, wenn ich einen Befehl erfolgreich beenden musste, habe ich verwendet || true. Wird || :als idiomatischer angesehen?

Mark Rushakoff
quelle
Es ist erwähnenswert, dass ||:(ohne Leerzeichen) auch in bash gültig ist. Es macht das Gleiche wie || :oder || true.
Bruno Bronosky

Antworten:

38

truewurde nicht in die Bourne-Shell eingebaut. :immer war (es war der Weg, Kommentare einzugeben, bevor #eingeführt wurde).

Das, und weil es kürzer Typ ist , ist wahrscheinlich der Hauptgrund , warum Menschen es vorziehen , :über true.

Beachten Sie einen weiteren Unterschied bei POSIX-Shells (z. B. bashnur im POSIX-Modus): while trueist ein reguläres Builtin (muss nicht einmal eingebaut sein), :ist ein spezielles Builtin. Dies hat einige Auswirkungen, von denen die meisten in diesem speziellen Fall wahrscheinlich keine Auswirkungen haben:

  • Wenn ein :Befehl fehlschlägt, auch aufgrund einer fehlgeschlagenen Umleitung, wird die Shell beendet. In der Praxis wird das wahrscheinlich keinen Unterschied machen, wenn Sie Weiterleitungen an weiterleiten:

    $ sh -c ': > /   ; echo HERE'
    sh: 1: cannot create /: Is a directory
    $ sh -c 'true > /; echo HERE'
    sh: 1: cannot create /: Is a directory
    HERE
  • in var=value :, varbleibt valuenach :Rücksendung gesetzt, nicht bei true:

    $ var=1; var=2 :   ; echo "$var"
    2
    $ var=1; var=2 true; echo "$var"
    1

Beachten Sie auch , dass die || trueArbeiten in Schalen von der rcund cshFamilien , aber nicht || :(aber nicht abbrechen set -ein csh).

|| :ist nicht dasselbe wie :. Es bedeutet oder läuft :anders (das heißt, wenn die vorhergehende Pipeline ausfällt).

set -e
false

Würde bewirken , dass die Schale zu Ausfahrt aufgrund set -eund falsehat einen von Null (failure) Exit - Status. Der set -eEffekt wird abgebrochen, wenn der Befehl, der einen Exit-Status ungleich Null zurückgibt, als Bedingung verwendet wird, wie in:

if false; then ...
while false; do ...
false && : ...
false || : ...

false && :nur storniert set -e. false || :Bricht set -eden Exit-Status ab und setzt ihn auf, 0so dass es idiomatischer ist, zu sagen, dass wir einen fehlerhaften Exit-Code des Befehls ignorieren möchten. Die meisten würden argumentieren, dass dies || truebesser lesbar ist (was die Absicht klarer vermittelt).

Stéphane Chazelas
quelle
5
&& :ist genial, gibt es irgendwelche Dokumente oder weiterführende Literatur dazu? Google fällt mir beim Versuch, diese Art von Keywords zu finden, nicht aus…
Ian Bytchek
5

Im Allgemeinen ist in bash der Doppelpunkt :und truegleichwertig.

Ist || : für idiomatischer gehalten?

Ich denke, es basiert auf dem Kontext .

Wenn Sie möchten return value, dass a oder a conditionimmer wahr ist, sollten Sie ein trueSchlüsselwort verwenden. Dadurch wird Ihr Code klarer und die Betrachter erfahren, dass Sie den Wert wahr hervorheben möchten , dh:

while true; do something

oder

<commnad>
RETURN_VALUE= $? || true

Und wenn Sie nichts tun möchten oder NOPin der Shell, sollten Sie Doppelpunkt verwenden:

if condition
then
    : # DO NOTHING HERE
else
    do something
fi 

oder

while conditon
do
    : # DO NOTHING HERE
done
cuonglm
quelle
5

Die meisten dieser Antworten richten sich nicht an die am häufigsten verwendete Verwendung von :.

Erstens bezieht sich diese Diskussion nicht auf eine Shell, die kein Bourne-shell ( sh) -Derivat ist. Das heißt, alle Bourne-Derivat-Shells sehen trueund :als das Gleiche. Früher wurden Programmierer dazu ermutigt, :anstelle von zu verwenden true, da :es immer eine integrierte Version gibt, während es früher Fälle gab, in denen truenicht immer eine integrierte Version vorhanden war.

:hat zwei Verwendungen. Es ist kein Synonym für #, hat aber eine andere Funktion. Wenn Sie Ihr Skript unter a debuggen set -x, werden Zeilen, in denen sie #verwendet werden, vom Parser gelöscht und vollständig ignoriert, während Zeilen mit :analysiert und ausgewertet werden. Dies ist beim Debuggen sehr nützlich, da in -xdiesen Zeilen der Wert nach der Auswertung angezeigt wird. Es ist, als würden Sie printAnweisungen in Ihren Code einfügen, die nur im -xModus angezeigt werden. Seien Sie vorsichtig mit den Werten nach dem, :da es sich um echten Code handelt und die Nebenwirkungen Ihr Programm beeinflussen können.

cdr
quelle
1
Was ist die zweite Verwendung?
Peter Mortensen