2013-07-11 3 views
104

Manchmal, wenn ich Bedingungen mache, brauche ich den Code, nichts zu tun, zB hier möchte ich BASH nichts tun, wenn $a größer als "10" ist, drucken Sie "1", wenn $a ist kleiner als "5", andernfalls drucken "2":Welcher Befehl bedeutet in einer Bedingung in BASH "nichts tun"?

if [ "$a" -ge 10 ] 
then 
elif [ "$a" -le 5 ] 
then 
    echo "1" 
else 
    echo "2" 
fi 

Dies macht jedoch einen Fehler. Gibt es einen Befehl, der nichts bewirkt und mein Skript nicht verlangsamt?

Antwort

207

Der No-Op-Befehl in der Shell lautet : (Doppelpunkt).

if [ "$a" -ge 10 ] 
then 
    : 
elif [ "$a" -le 5 ] 
then 
    echo "1" 
else 
    echo "2" 
fi 

Vom bash manual:

: (ein Doppelpunkt)
Tue nichts über Argumente erweitern und Umleitungen durchführen. Der Rückkehrstatus ist Null.

+0

für Bildung, ist ein Operator, um "wahr" zu laufen. Ich bevorzuge in Fällen wie diesen viel wahrer, da es viel einfacher zu lesen ist. – SaintHax

+1

@SaintHax Nein, es läuft nicht "wahr". Es ist in die Shell eingebaut und tut nichts. – Barmar

+1

es ist Shell eingebaut (Sie sind richtig), es gibt wahr (Status 0) genau wie wahr, und es ist schwieriger zu lesen. Bash ist eine DevOps-Sprache, und wenn ':' von jemandem in meinem Team geschrieben wird, würde ich es ändern. – SaintHax

28

Sie können sich wahrscheinlich nur den true Befehl:

if [ "$a" -ge 10 ]; then 
    true 
elif [ "$a" -le 5 ]; then 
    echo "1" 
else 
    echo "2" 
fi 

Eine Alternative, im Beispielfall (aber nicht unbedingt überall) ist Ihre neu zu bestellen, wenn/else:

if [ "$a" -le 5 ]; then 
    echo "1" 
elif [ "$a" -lt 10 ]; then 
    echo "2" 
fi 
+7

Wenn Sie das Ergebnis nicht testen, sind sowohl "true" als auch "false" im Hinblick auf das Skript effektiv No-Ops, aber im Prinzip könnten sie * in einigen Shells forcen, die diese Syntax vielleicht akzeptieren ':' ist besser. – dmckee

+2

Die Frage ist markiert bash. In bash sind 'true' und' false' eingebaut. Für ältere Shells können 'true',' false' und sogar ':' externe Befehle sein (obwohl Sie diese wahrscheinlich nur in * sehr * alten Shells sehen würden). –

+4

Ich bevorzuge ':' einfach weil es expliziter ist, was die Absicht ist –

9

Obwohl ich nicht die ursprüngliche Frage zu beantworten concering die no-op-Befehl, viele (wenn nicht die meisten) Probleme, wenn man vielleicht denken, „in diesem Zweig ich nichts zu tun haben“ kann durch einfaches umgangen werden Umstrukturierung der Logik, so dass diese Verzweigung nicht auftreten wird.

Ich versuche, eine allgemeine Regel zu geben, indem das OPs Beispiel

nichts tun zu verwenden, wenn $ a größer als "10" ist, print "1", wenn $ a kleiner als "5", sonst, print „2“

wir haben eine Niederlassung zu vermeiden, wo $a mehr als 10 bekommt, so $a < 10 als eine allgemeine Bedingung folgende Bedingung zu jedem anderen, angewendet werden kann.

Im Allgemeinen, wenn Sie nichts sagen, wenn X, dann ist es als einen Zweig vermeiden umformulieren, wo X. Normalerweise können Sie die Vermeidung dadurch erreichen, dass Sie einfach X negieren und auf alle anderen Bedingungen anwenden.

das OPs Beispiel mit der Regel so umstrukturiert, angewandt werden:

if [ "$a" -lt 10 ] && [ "$a" -le 5 ] 
then 
    echo "1" 
elif [ "$a" -lt 10 ] 
then 
    echo "2" 
fi 

nur eine Variation des oben, umschließt alles im $a < 10 Zustand:

if [ "$a" -lt 10 ] 
then 
    if [ "$a" -le 5 ] 
    then 
     echo "1" 
    else 
     echo "2" 
    fi 
fi 

(Für dieses spezielle Beispiel @Flimzys restructuring ist sicherlich besser, aber ich wollte eine allgemeine Regel für all die Leute geben, die suchen, wie man nichts macht.)

+0

Ein Grund, warum jemand ein No-Op haben möchte, ist, wenn man den Code anfänglich strukturiert, mit der Idee, dass man später etwas hinzufügt, ohne unbeabsichtigte Nebenwirkungen zu haben. Z.B. Wenn man ein if-then-else-fi in eine .bashrc legt, wenn man 'echo 'hier hineinlegt" ", wird es einige der Nicht-Login-Benutzungen zerstören (zB scp wird kaputt gemacht), und nur whitespace/Kommentare verursachen einen Laufzeitfehler. – Aphoid