Frage Bash Loop - Wie kann ich den Loop stoppen, wenn ich in einem Befehl Control-C drücke?


Ich rsyncing ein paar Verzeichnisse. Ich habe ein Bash-Terminal geöffnet und führe so etwas aus:

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

Wenn ich jedoch die ganzen Dinge stoppen will, drücke ich Control-C. Das stoppt das rsync, aber dann geht es weiter zum nächsten. In diesem Fall erkenne ich, was passiert ist, und drücke Control-C einfach wie ein Verrückter, bis alles wieder funktioniert.

Gibt es einen Weg, das zu "reparieren"? Ich möchte es also, wenn ich einen solchen Loop habe und Control-C drücke, dass er mich zu meiner Bash-Shell zurückbringt.


32
2018-01-22 15:09


Ursprung


Dennis 'Antwort ist die richtige, aber wenn du das nicht getan hast, musst du es nicht "wie ein Verrückter" drücken, halt es einfach und lass die Tastatur wiederholen :-) - Kyle Brandt♦
Ich halte immer nur Cntl-C, im Allgemeinen funktioniert gut. - Scott Alan Miller


Antworten:


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

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


28
2018-02-03 19:03



Fantastische, elegante, unvergessliche Lösung. Vielen Dank! - mmocny
Zusätzlicher Tipp: Wenn Sie sich in einer verschachtelten Schleife befinden und vollständig terminieren möchten, verwenden Sie break 2 (oder ersetzen Sie "2" durch die Anzahl der verschachtelten Schleifen, die Sie beenden möchten). - Dolan Antenucci


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

trap <command> SIGINT

wird das ausführen command wenn Strg-C gedrückt wird. Stellen Sie einfach die trap Anweisung irgendwo in Ihrem Skript an einem Punkt, wo Sie es wirksam werden wollen.


23
2018-01-22 15:16





Um die Antwort von Dennis zu erweitern, könnte Ihr Code wie folgt aussehen:

trap "echo Exited!; exit;" SIGINT SIGTERM

Für ein funktionierendes Beispiel (das rsync mit einbezieht), check out http://gist.github.com/279849.


21
2017-07-16 00:17



Danke, das ist eine generische Lösung, die für mich funktioniert hat - wi1


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

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

Aber! Im Falle der rsync Befehl, es erlaubt mehrere Quellen, so dass der Code, den Sie geschrieben haben, besser geschrieben wäre als:

rsync -a * example.com:somewhere/

6
2018-02-22 04:06





  1. Drücken Sie Ctrl-Z das Skript anhalten;
  2. kill %%

Kredite, Erklärungen und mehr Details in diese Antwort.


5
2017-08-03 10:29





Ich neige dazu, einen weiteren Befehl in meine Schleife einzufügen, der leicht unterbrochen werden kann. Es erfordert, dass zwei Ctrl-C gedrückt werden.

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

Es ist nicht so eine großartige Lösung für dieses rsync, das 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

Diese Schleife sucht die Adresse von example.com jedes Mal erneut durch die Schleife, was nützlich ist, wenn Sie nach einer DNS-Änderung Ausschau halten.


0
2018-03-04 15:53