Bash, der Interrupts während rsync / subshell exec-Anweisungen nicht abfängt

9

Kontext:

Ich habe ein Bash-Skript, das eine Subshell und einen Trap für das Pseudo-Signal EXIT enthält und Interrupts während eines rsync nicht korrekt abfängt. Hier ist ein Beispiel:

%Vor%

Die Idee des Skripts ist folgende: Die meiste wichtige Logik läuft in einer Subshell, die durch tee und eine Logdatei geleitet wird, also muss ich nicht jede einzelne Zeile der Hauptlogik tee Lass es alles geloggt werden. Immer wenn die Subshell endet oder das Skript aus irgendeinem Grund angehalten wird (das EXIT-Pseudosignal sollte alle diese Fälle erfassen), fängt der Trap es ab und führt die cleanup() -Funktion aus und entfernt dann den Trap. Die Befehle rsync und sleep (der Ruhezustand ist nur ein Beispiel) werden durch exec ausgeführt, um die Erstellung von Zombie-Prozessen zu verhindern, wenn ich das übergeordnete Skript während der Ausführung und jeden potenziell lang laufenden Befehl abbringe ist in eine eigene Subshell eingebunden, so dass bei Beendigung von exec das ganze Skript nicht beendet wird.

Das Problem:

Wenn ich das Skript (über kill oder STRG + C) während des Befehls exec / subshell wrapped sleep abbringe, funktioniert das Trap korrekt und ich sehe "Cleaning up!" echoed und protokolliert. Wenn ich das Skript während des Befehls rsync abbringe, sehe ich rsync end und schreibe rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(544) [sender=3.0.6] auf den Bildschirm, und dann stirbt das Skript ab; keine Aufräumarbeiten, keine Überfüllung. Warum löst eine Unterbrechung / Abtötung von rsync die Falle nicht aus?

Ich habe versucht, den Schalter --no-detach mit rsync zu verwenden, aber es hat nichts geändert. Ich habe Bash 4.1.2, rsync 3.0.6, CentOS 6.2.

    
Zac B 08.03.2012, 21:06
quelle

4 Antworten

1

Wie wäre es, wenn die gesamte Ausgabe von Punkt X auf Tee umgeleitet wird, ohne es überall wiederholen zu müssen und sich mit allen Sub-Shells und Execs herumzuschlagen ... (hoffe, ich habe nichts verpasst)

%Vor%     
nhed 04.06.2012, 02:14
quelle
1

Der Interrupt wird korrekt abgefangen, wenn Sie INT dem Trap hinzufügen

%Vor%

Bash fängt die Überfüllung korrekt ab. Dies stellt jedoch nicht die Frage, warum das Skript beim Beenden abfängt, wenn sleep unterbrochen ist, oder warum es nicht auf rsync triggert, sondern das Skript so ausführt, wie es soll. Hoffe, das hilft.

    
Jari Laamanen 16.03.2012 15:27
quelle
1

Zusätzlich zu set -e denke ich, dass du set -E :

möchtest
  

Falls gesetzt, wird jeder Trap auf ERR von Shell-Funktionen, Befehlsersetzungen und Befehlen in einer Subshell-Umgebung geerbt. Die ERR-Falle wird normalerweise in solchen Fällen nicht vererbt.

Alternativ können Sie, statt Ihre Befehle in Subshells zu verpacken, geschweifte Klammern verwenden, die Ihnen weiterhin die Möglichkeit geben, Befehlsausgaben umzuleiten, aber sie in der aktuellen Shell ausführen.

    
Stephen Niedzielski 04.06.2012 01:21
quelle
0

Ihre Shell ist möglicherweise so konfiguriert, dass sie bei einem Fehler beendet wird:

%Vor%

Wenn Sie sleep (^ C) unterbrechen, wird die Untershell aufgrund von set -e und print woah im Prozess beendet.

Auch etwas unzusammenhängend: Ihr trap - EXIT befindet sich (explizit) in einer Subshell, also hat es keine Wirkung, nachdem die Aufräumfunktion

zurückgibt     
sehe 16.03.2012 15:55
quelle

Tags und Links