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.