Bash-Schleife - Wie kann ich die Schleife anhalten, wenn ich in einem Befehl die Strg-C-Taste drücke?

35

Ich synchronisiere ein paar Verzeichnisse. Ich habe ein Bash-Terminal geöffnet und führe Folgendes aus:

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done

Wenn ich jedoch das Ganze stoppen möchte, drücke ich Strg-C. Das stoppt den Rsync, aber dann geht es weiter zum nächsten. In diesem Fall merke ich, was passiert ist und drücke dann einfach wie ein Verrückter die Strg-Taste, bis die Dinge wieder funktionieren.

Gibt es eine Möglichkeit, dies zu beheben? Wenn ich eine solche Schleife habe und Strg-C drücke, möchte ich, dass ich wieder zu meiner Bash-Shell zurückkomme.

Rory
quelle
6
Dennis 'Antwort ist die richtige, aber wenn Sie das nicht getan haben, müssen Sie es nicht wie ein Verrückter drücken. Halten Sie es einfach und lassen Sie die Tastatur wiederholen :-)
Kyle Brandt
Ich halte immer nur Cntl-C gedrückt, funktioniert im Allgemeinen gut.
Scott Alan Miller

Antworten:

33
for DIR in * ; do rsync -a $DIR example.com:somewhere/ || break; done

Dies beendet auch die Schleife, wenn ein einzelner rsync-Lauf aus irgendeinem Grund fehlschlägt.

Kenster
quelle
4
Zusätzlicher Tipp: Wenn Sie sich in einer verschachtelten Schleife befinden und diese vollständig beenden möchten, verwenden Sie break 2(oder ersetzen Sie "2" durch die Anzahl der verschachtelten Schleifen, die Sie beenden möchten).
Dolan Antenucci
26

Um die Antwort von Dennis zu erweitern, könnte Ihr Code folgendermaßen aussehen:

trap "echo Exited!; exit;" SIGINT SIGTERM

Ein funktionierendes Beispiel (das zufällig rsync beinhaltet) finden Sie unter http://gist.github.com/279849 .

Ian Greenleaf Young
quelle
Vielen Dank, dies ist eine generische Lösung, die für mich funktioniert hat
wi1
25

Sie können eine Falle für Control-C einrichten.

trap <command> SIGINT

wird ausgeführt, commandwenn Control-C gedrückt wird. Platzieren Sie die trapAnweisung einfach an einer beliebigen Stelle in Ihrem Skript, an der sie wirksam werden soll.

Bis auf weiteres angehalten.
quelle
6

Wenn Sie eine Befehlsfolge in runde Klammern setzen, fungiert die Zeichenfolge als ein einzelner Prozess und empfängt das ZEICHEN und wird beendet, wenn Sie Ctrl- drücken C:

(for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; done)

Aber! Im Fall des rsyncBefehls sind mehrere Quellen zulässig, sodass der von Ihnen geschriebene Code besser geschrieben wäre als:

rsync -a * example.com:somewhere/
Amphetamachine
quelle
6
  1. Drücken Sie Ctrl-Z, um das Skript anzuhalten.
  2. kill %%

Credits, Erklärungen und weitere Details in dieser Antwort .

Skippy le Grand Gourou
quelle
Das ist großartig, weil es "post facto" funktioniert, wenn Sie eine bereits begonnene Langzeitschleife unterbrechen möchten.
Nick Matteo
0

Ich neige dazu, einen anderen Befehl in meine Schleife einzufügen, der leicht unterbrochen werden kann. Es müssen zwei Strg-C gedrückt werden.

for DIR in * ; do rsync -a $DIR example.com:somewhere/ ; sleep 1 ; done

Es ist keine so gute Lösung für diesen Rsync, den Sie wahrscheinlich schnell ausführen möchten. Aber es funktioniert gut für andere Schleifen, wie diese:

while true ; do ping -c 10 example.com ; sleep 1 ; done

In dieser Schleife wird die Adresse von example.com jedes Mal neu gesucht. Dies ist hilfreich, wenn Sie nach einer DNS-Änderung Ausschau halten.

Alan Porter
quelle