Führen Sie einen Befehl nach Beendigung in Bash fortlaufend erneut aus

62

Ich versuche, eine einfache Möglichkeit zu finden, um einen Befehl immer dann erneut auszuführen, wenn er beendet wird, aus irgendeinem Grund (Fehler oder auf andere Weise).

Was wäre der beste Weg, dies zu erreichen?

EDIT: Ich war vorher nicht klar genug. Ich brauche die nächste Ausführung, um zu warten, bis die vorherige beendet ist.

EDIT 2: Fast alle Antworten funktionieren prima. Ich dachte fälschlicherweise, dass die meisten Antworten den Prozess entweder verzögern oder ihn nur einmal erneut ausführen würden, was nicht erwünscht ist.


quelle
1
Du bist immer noch nicht klar. Es wäre hilfreich, wenn Sie erwähnen würden, welches Programm Sie ausführen.
Daniel Beck
1
-1 Diese Frage zeigt keinen Forschungsaufwand, da der Benutzer bemerkte, dass die Antworten nicht funktionierten, anstatt tatsächlich zu versuchen, das zu tun, was sie vorschlagen.
Daniel Beck

Antworten:

39

Dies erzeugt eine Endlosschleife, die commandimmer wieder ausgeführt wird.

while :
    do
        command
done
Dennis
quelle
Bitte beachten Sie die Bearbeitung der ursprünglichen Frage. Ich muss es immer wieder ausführen, nicht nur einmal.
8
@calcifer Diese Antwort funktioniert ganz gut. Es gibt etwas Ungewöhnliches an Ihrem Programm, das keiner der vier Benutzer erwartet hat und das Sie nicht erwähnt haben.
Daniel Beck
@calcifer das ist eine Endlosschleife. es wiederholt sich bis zum Ende der Zeit (na ja, bis das Skript beendet ist)
Nate Koppenhaver
1
Meine schlechte, ich dachte, dies (und alle anderen Antworten) wird entweder den Prozess verkürzen oder ihn nur einmal erneut ausführen, was nicht erwünscht ist. Also ja, diese Antwort funktioniert. Vielen Dank.
1
Einzeilige Version: while true; do echo 'Hit CTRL+C'; sleep 1; donedank cyberciti.biz/faq/bash-infinite-loop
jk2K
107

Der watchBefehl wiederholt einen Befehl für immer mit einem festgelegten Intervall:

watch -n0 <command>

Das Setzen -nauf Null setzt das Intervall effektiv auf Null (ich denke, es ist wirklich 0,1 Sekunden).

watch Darüber hinaus bietet es den zusätzlichen Vorteil, die Ausgabe so auszurichten, dass visuelle Änderungen leicht sichtbar sind, und verfügt über einen Schalter zum Hervorheben von Änderungen seit der letzten Ausführung.

Referenz: die Watchmanpage :

watch führt den Befehl wiederholt aus und zeigt seine Ausgabe an (die erste Bildschirmausgabe). Auf diese Weise können Sie beobachten, wie sich die Programmausgabe im Laufe der Zeit ändert. Standardmäßig wird das Programm alle 2 Sekunden ausgeführt. Verwenden Sie -n oder --interval, um ein anderes Intervall anzugeben.

Die Uhr läuft, bis sie unterbrochen wird.

Paul
quelle
Bitte beachten Sie die Bearbeitung der ursprünglichen Frage.
6
Alle bisherigen Antworten tun dies, einschließlich dieser. Linux gibt nicht auf, wenn Sie es nicht ausdrücklich darum bitten.
Paul
Ich wusste das nicht über Gabel, danke.
Ich kann mit dieser Methode keine Ausgabe sehen.
Raffi Khatchadourian
@ RaffiKhatchadourian Wollen Sie damit sagen, dass Sie watch lsin einem Verzeichnis, das Dateien enthält, nichts bekommen?
Paul
17

Eine einfache Lösung wäre:

yourcommand; !#

;trennt Befehle und ermöglicht mehrere Befehle in einer Zeile ( Bash: Lists )

!#fordert bash auf, "alles zu wiederholen, was ich bisher in dieser Zeile geschrieben habe" ( Bash: Event-Designators )

Blauer Himmel
quelle
1
Entschuldigung, ich war nicht klar genug. Ich muss es immer wieder ausführen, nicht nur einmal.
Danke dafür, ich habe danach gesucht, zumal yourcommand; !!eigentlich nicht mit Kommandos in der gleichen Zeile gearbeitet wird, aber !#zu tun scheint. Prost!
Sdaau
; !#hat bei ZSH nicht funktioniert, es erweitert nur die Aussage im Wesentlichen,
klont
7

Sie können während der Befehlsausführung im Voraus planen (vorausgesetzt, es ist nicht interaktiv) und eingeben, !!welches Programm den vorherigen Befehl erneut ausführen soll. Dies funktioniert zB während ping -c 5.


Sie können eine Funktion auch definieren in bash:

function repeat { "$@"; "$@"; }

Um es zu speichern, speichern Sie es in ~/.bashrc.

Dann können Sie Ihren Befehl wie folgt ausführen:

repeat ping -c5 heise.de

Wenn es sich um einen bestimmten Befehl handelt, den Sie wiederholt ausführen möchten (und nicht z. B. einen Befehl), können Sie ihn "$@"in diesem Snippet durch Ihren tatsächlichen Befehl ersetzen und repeat_pingstattdessen z . B. die Funktion benennen .


Um es zu einer Endlosschleife zu machen, können Sie das tun, was @Dennis vorschlägt. Ich empfehle Ihnen, eine Wartezeit hinzuzufügen, wenn Sie dies in einer interaktiven Shell verwenden möchten:

function repeat { while 1 ; do "$@" ; sleep 1 ; done; }

Andernfalls ist es ziemlich unpraktisch, diese Endlosschleife mit abzubrechen Ctrl-Z.

Daniel Beck
quelle
Bitte beachten Sie die Bearbeitung der ursprünglichen Frage.
6
@calcifer Diese Ausführungen warten, bis der Programmaufruf zurückkehrt. Trennt sich Ihr Programm von der Shell und kehrt zurück, bevor es beendet wird?
Daniel Beck
Meine schlechte, ich dachte, dies (und alle anderen Antworten) wird entweder den Prozess verkürzen oder ihn nur einmal erneut ausführen, was nicht erwünscht ist. Also ja, diese Antwort funktioniert. Vielen Dank.
4

Geben Sie einer whileSchleife eine boolesche Bedingung wie folgt:

#!/bin/bash

while true; do

    do_something && wait

done

Dies wird immer wieder ausgeführt, bis die Bash ein Signal zum Beenden des Prozesses erhält. Normalerweise in Form von ctrl+c.

Sie können den watchBefehl auch verwenden , um ein Skript wiederholt auszuführen. Zum Beispiel könnte eine einfache Uhr in Ihrem Bash-Terminal folgendermaßen watchaussehen:

$ watch -t -n1 date +%T

Die -tOption gibt watchan, dass kein Titel des ausgeführten Prozesses angezeigt werden soll. Dadurch erhalten Sie eine saubere Ausgabe nur des Befehls, der wiederholt wird. Die -n1Option weist die Uhr an, sich alle nSekunden zu wiederholen . In diesem Fall -n1werden Intervalle von 1Sekunden sein. Dann date +%Tzeigt der Befehl die Zeit zum Zeitpunkt der Befehlsbeendigung an. Durch Ausführen dieses Befehls erhalten Sie eine aktive Uhr in Ihrem Terminal.

Und dann wäre eine weitere Methode, die in keiner der anderen Antworten enthalten ist, ein unendlicher Funktionsaufruf.

do_something() { do_something }; do_something && wait

Dies ist im Wesentlichen dasselbe wie die Boolesche whileSchleife, die nur rekursive Funktionsaufrufe verwendet.

(Bearbeiten) Um die Ressourcen Ihres Rechners im Auge zu behalten, habe ich die hinzugefügt, && waitdamit jedes Mal, wenn ein Prozess ausgeführt wird, die Schleifen "warten", bis dieser Prozess mit dem Beendigungsstatus 0 endet, bevor die nächste Iteration erfolgt. Dies ist in einem interaktiven Shell-Skript nützlich.


quelle
1
Es gibt ein whileSchleifenbeispiel, das jedoch keine boolesche trueSyntax verwendet. Es gibt ein watchBeispiel, aber es gibt nicht viele nützliche Syntax. Ich erkläre dies für wen es auch helfen mag. Ich wollte diesen etwas praktischen Nutzen geben. Der whileSchleifen-Boolesche Wert kann auch ausgeführt werden falseund erst dann ausgeführt werden, wenn eine unwahre Bedingung erfüllt ist. Es ist sehr praktisch.
1
@ Spittin'IT Es wurde eine Methode hinzugefügt, die für Ihre Bequemlichkeit in anderen Antworten nicht verwendet wird.
Fair genug und ich verstehe ... Ich habe gerade einen Kommentar abgegeben, als ich das Review-Modul durchgesehen habe.
Pimp Juice IT
Wie wird ifdie Ausführung fortgesetzt?
Kamil Maciorowski
Guter Punkt, Kamil. Vergaß es rekursiv zu machen lol. Beim Bearbeiten mit einer Funktion behoben, die sich in der ifAnweisung selbst aufruft .
0

Dies ist eine andere Methode, die ich verwende, um einen Befehl in bash zu wiederholen. Dies mag für manche albern klingen, da sie kein Skript schreiben müssen und vielen bekannt sein könnten. Aber ich denke, es ist erwähnenswert, da es schnell und anfängerfreundlich ist, in dem Sinne, dass es nicht viel Syntax gibt, an die man sich erinnern kann. Ich habe dies nur in gnome-terminal von Ubuntu getestet und andere Terminals unterstützen dies möglicherweise nicht.

  1. Geben Sie den Befehl einmal im Terminal ein.
  2. Wählen Sie den Befehl einschließlich Zeilenumbruch mit der Maus aus.
  3. Kopieren Sie die Auswahl mit Strg-Einfügen oder über das Kontextmenü (normalerweise mit einem Rechtsklick).
  4. Verwenden Sie Umschalt-Einfügen, um so oft einzufügen, wie Sie den Befehl ausführen möchten.

Sie müssen nicht warten, bis die einzelnen Befehle ausgeführt wurden. Die eingefügten Befehle werden in eine Warteschlange gestellt und nacheinander ausgeführt.

jayadeepk
quelle
0

Ich fühle mich heute frech.

Lesen Sie aus einem der unendlichen Streams und leiten Sie es an xargs

cat /dev/zero | xargs --null echo hello there

Wenn Sie dort eine kleine Pause einlegen müssen, müssen Sie wahrscheinlich ausführen sh

cat /dev/zero | xargs --null sh -c "echo hello there && sleep 3"
Jefferey Höhle
quelle