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.


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.


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 .


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.


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/

6
  1. Drücken Sie Ctrl-Z, um das Skript anzuhalten.
  2. kill %%

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


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.