Question

Je peux écrire des scripts shell qui piégent SIGINT C'est très bien, mais je n'arrive pas à piéger SIGQUIT.

#!/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

Exécuter ce script et appuyer sur CTRL-C a l'effet souhaité, mais pressant CTRL-\ (Ce qui, selon moi, devrait déclencher SIGQUIT) ne fait rien sauf imprimer ^\ dans le terminal. Pourquoi?

J'ai deux théories de course. La première est que la sémantique de SIGINT et SIGQUIT sont différents tels que SIGQUIT est uniquement envoyé au processus de l'enfant sleep, tandis que SIGINT est envoyé à la fois au processus enfant et au processus de bash de parents. Si tel est le cas, où est-il documenté?

Ma deuxième théorie est que Bash ignore non seulement (c'est-à-dire, un gestionnaire sans op) pour) SIGQUIT Par défaut (comme la page Man le suggère), mais ne lui permet pas d'être piégé du tout. Cette théorie chevauche la première théorie, car il pourrait être le cas que SIGQUIT va chez le parent et l'enfant, mais le parent (bash) Je ne peux pas le piéger. Si c'est le cas, est là n'importe quel façon de piéger SIGQUIT Dans un script bash? ... peut-être certains shopt Je peux définir?

Edit: Ceci est sur Ubuntu 10.10 dans GNOME-terminal 2.32.0 Running Bash 4.1.5, et oui ^\ est configuré pour émettre Sigquit (comme indiqué par stty -a et confirmé en émettant ^\ Sigquits à d'autres programmes comme ping).

MISE À JOUR: Je viens de découvrir que le problème doit être dû en quelque sorte au gnome-terminal. Si j'exécute ce script à partir d'une console virtuelle (c'est-à-dire, ctrl-alt-f1 Pour sortir de x), il emprisonne parfaitement Sigquit quand j'appuie ^\. Même bash et tout, donc la seule différence doit être l'émulateur terminal. Alors maintenant, ma question devient: comment puis-je configurer le gnome-terminal pour se comporter comme la console virtuelle à cet égard? je diff'D les sorties de stty -a Dans la console virtuelle et dans le gnome-terminal, et bien qu'il y ait des différences, rien ne semble immédiatement pertinent (par exemple, ils ont tous les deux quit = ^\;).

MISE À JOUR 2: Une autre expérience. Exécuter simplement $ sleep 60 en terminal gnome; presse ^\ Et le signal ne va pas. Exécutez maintenant $ sleep 60 dans la console virtuelle; presse ^\ Et le signal est attrapé - le processus imprime Quit et sors. Mais maintenant courir $ ping google.com dans Gnome-terminal et presse ^\ - Le signal est capturé et manipulé comme prévu. Il y a donc quelque chose de bizarre dans le gnome-terminal tel que Sigquit peut être pris par certains programmes, mais pas par d'autres, même si ces autres fais Catchez-le lorsqu'il est invoqué à partir de la console virtuelle. Je devrais peut-être mettre à niveau mon gnome-terminal.

Était-ce utile?

La solution

Je peux seulement supposer qu'il s'agissait d'une sorte de bug dans le gnome-terminal 2.32.0; Depuis, je suis passé à Ubuntu 11.04, avec un gnome-terminal 2.32.1 (et bash 4.2.8) et Sigquit est maintenant piégé comme prévu.

Autres conseils

J'observe le même comportement sur Fedora 19 avec xfce: selon ps s, bash dans le terminal XFCE4 a ignoré Sigquit, en cours d'exécution yes >/dev/null & et alors ps s montre que même un sous-processus a ignoré Sigquit. Quand je (du même terminal) je cours ssh localhost, la coquille de la session SSH a également ignoré Sigquit, mais yes >/dev/null & n'a pas.

Compte tenu du commentaire ci-dessus qui mentionne le gnome-terminal, je suppose que le bug est dans la partie commune des deux terminaux: le vte bibliothèque. Le mien est vte-0.28.2-9.fc19.x86_64.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top