Frage

Ich kann Shell-Skripte schreiben, die SIGINT einfangen, aber ich kann SIGQUIT nicht einfangen.

#!/bin/bash

function die {
    echo "Dying on signal $1"
    exit 0
}

trap 'die "SIGINT"' SIGINT
trap 'die "SIGQUIT"' SIGQUIT

while true; do
    echo "sleeping..."
    sleep 5
done

Das Ausführen dieses Skripts und das Drücken von CTRL-C hat den gewünschten Effekt, aber das Drücken von CTRL-\ (der meines Wissens SIGQUIT auslösen sollte) bewirkt nichts anderes als das Drucken von ^\ im Terminal. Warum?

Ich habe zwei laufende Theorien. Das erste ist, dass die Semantik von SIGINT und SIGQUIT unterschiedlich ist, so dass SIGQUIT nur an den untergeordneten Prozess sleep gesendet wird, während SIGINT sowohl an den untergeordneten Prozess als auch an den übergeordneten Bash-Prozess gesendet wird. Wenn dies der Fall ist, wo wird es dokumentiert?

Meine zweite Theorie besagt, dass bash SIGQUIT standardmäßig nicht nur ignoriert (d. h. einen No-Op-Handler für) hat (wie in der Manpage vorgeschlagen), sondern es überhaupt nicht zulässt, dass er abgefangen wird. Diese Theorie überschneidet sich mit der ersten Theorie, da es sein könnte, dass SIGQUIT sowohl an Eltern als auch an Kinder geht, aber die Eltern (bash) können ihn einfach nicht einfangen. Wenn dies der Fall ist, gibt es eine Möglichkeit, SIGQUIT in einem Bash-Skript abzufangen? ... vielleicht einen shopt, den ich festlegen kann?

Bearbeiten: Dies ist unter Ubuntu 10.10 in gnome-terminal 2.32.0, auf dem bash 4.1.5 ausgeführt wird, und ja, ^\ ist für die Ausgabe von SIGQUIT konfiguriert (wie durch stty -a gemeldet und durch Ausgabe von ^\ SIGQUITs an andere Programme wie ping bestätigt) / p>

UPDATE: Ich habe gerade entdeckt, dass das Problem irgendwie am Gnome-Terminal liegen muss. Wenn ich dieses Skript von einer virtuellen Konsole aus ausführe (d. H. ctrl-alt-f1, um aus X herauszukommen), wird SIGQUIT einwandfrei abgefangen, wenn ich ^\ drücke. Gleiche Bash und alles, also muss der einzige Unterschied der Terminalemulator sein. Nun stellt sich meine Frage: Wie kann ich das Gnome-Terminal so konfigurieren, dass es sich in dieser Hinsicht wie die virtuelle Konsole verhält? Ich habe die Ausgaben von diff in der virtuellen Konsole und im Gnome-Terminal stty -a, und obwohl es Unterschiede gibt, scheint nichts unmittelbar relevant zu sein (z. B. haben beide quit = ^\;).

UPDATE 2: Ein weiteres Experiment. Führen Sie einfach $ sleep 60 im gnome-terminal aus; Drücken Sie ^\ und das Signal wird nicht erfasst. Führen Sie nun $ sleep 60 in der virtuellen Konsole aus. Drücken Sie ^\ und das Signal wird abgefangen - der Prozess druckt Quit und wird beendet. Führen Sie nun $ ping google.com im gnome-terminal aus und drücken Sie ^\ - das Signal wird wie erwartet abgefangen und verarbeitet. Das Gnome-Terminal hat also etwas Seltsames, so dass SIGQUIT von einigen Programmen abgefangen werden kann, von anderen jedoch nicht, selbst wenn diese anderen es abfangen, wenn sie von der virtuellen Konsole aufgerufen werden. Vielleicht sollte ich einfach mein Gnome-Terminal aktualisieren.

War es hilfreich?

Lösung

Ich kann nur annehmen, dass dies eine Art Fehler in Gnome-Terminal 2.32.0 war;Ich habe seitdem ein Upgrade auf Ubuntu 11.04 mit Gnome-Terminal 2.32.1 (und Bash 4.2.8) durchgeführt und SIGQUIT ist jetzt wie erwartet gefangen.

Andere Tipps

Ich beobachte das gleiche Verhalten unter Fedora 19 mit XFCE: Laut ps s hat bash im xfce4-Terminal SIGQUIT ignoriert, yes >/dev/null & wird ausgeführt und dann zeigt ps s, dass selbst ein Unterprozess SIGQUIT ignoriert hat.Wenn ich (vom selben Terminal) ssh localhost ausführe, wird in der Shell in der ssh-Sitzung auch SIGQUIT ignoriert, yes >/dev/null & jedoch nicht.

Angesichts des obigen Kommentars, in dem das Gnome-Terminal erwähnt wird, würde ich vermuten, dass der Fehler im gemeinsamen Teil der beiden Terminals liegt: der vte-Bibliothek.Meins ist vte-0.28.2-9.fc19.x86_64.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top