Wie führe ich einen Befehl aus und erhalte den Beendigungscode in weniger Zeichen?

13

Ich habe meine Skripte so geschrieben:

some_command
while [ $? -ne 0 ] ; do
    sleep 1
    some_command
done

Es hat mich immer geärgert, dass ich some_commandzweimal schreiben muss . Kann ich es irgendwie in den Loop-Testabschnitt legen?

Mihai
quelle

Antworten:

20

Sie könnten some_commandals Ihre Testbedingung verwenden.

while ! some_command; do sleep 1; done

Die Bedingung bleibt so lange wahr, wie sie some_commandmit einem Fehler beendet wird.

Oder ausführlicher, wenn Sie zusätzliche Prüfungen durchführen möchten:

while ! some_command
do 
    # add more if desired
    sleep 1
done
John WH Smith
quelle
Das sieht besser aus als meins, obwohl es ein Einzeiler ist ;-)
Anthon
Das OP möchte es vielleicht in mehrere Zeilen aufteilen, falls er bei einem Fehler mehrere Befehle ausführen muss :)
John WH Smith
Kein Grund, warum Sie es nicht in Semikolons trennen können, um es mehrzeilig zu machen.
Mark Stewart
1
... oder schreibewhile ! some_command; do several; commands; sleep 1; done
ignis
12

Dafür ist die untilSchleife gedacht:

until some_command
do    sleep 1
done

Es ist die logische Negation einer whileSchleife.

Die Spezifikation sagt:

Die untilSchleife

  • Die untilSchleife soll kontinuierlich eine Verbindungsliste ausführen, solange eine andere Verbindungsliste einen Nicht-Null-Ausgangsstatus hat.

  • Das Format der till-Schleife lautet wie folgt:

    bis Verbindungsliste-1
    Führe Verbindung-Liste-2 aus
    erledigt
  • Die zusammengesetzte Liste 1 soll ausgeführt werden, und wenn sie den Beendigungsstatus Null hat, wird der untilBefehl abgeschlossen. Andernfalls wird die Verbindungsliste 2 ausgeführt und der Vorgang wiederholt.
mikeserv
quelle
4

Sie können einfach Folgendes tun:

false
while [ $? -ne 0 ] ; do
   sleep 1
   some_command
done

dies hat jedoch den nachteil, dass es immer eine sekunde zuerst schläft

Wenn Sie in der Lage sein möchten, mit einer Reihe von Befehlen zu beenden, um mit 0 zu beenden, können Sie Folgendes tun:

while true; do
  if [ some_command ] ; then break ; fi
  if [ some_other_command ] ; then break ; fi
  sleep 1
done

das funktioniert natürlich auch nur für some_command

Anthon
quelle
5
Das zweite Beispiel sollte keine [und ]um die Befehle enthalten.
nyuszika7h
2

Weder funktioniert while ! ...noch until ...auf den Systemen, die ihre Shell-Umgebung vor POSIX.1-2001 eingefroren haben. Das tut es jedoch.

while :; do
    if some command; then
        break
    fi
    sleep 1
done

Wenn Sie keine vollständige Portabilität benötigen, warum schreiben Sie ein Shell-Skript? Perl ist mit größerer Wahrscheinlichkeit verfügbar als Bash.

sleep 1 while 0 != system qw(some command);

(Wie oben wird das sleepnur ausgeführt, wenn der Befehl fehlschlägt.)

zwol
quelle