44 votes

Pourquoi Ctrl-C ne tue-t-il pas le Terminal lui-même?

Le terminal fonctionne lorsque nous l'ouvrons.

luvpreet@DHARI-Inspiron-3542:/$

Je viens de l'ouvrir. Donc, lorsque j'appuie sur Ctrl+C, pourquoi ne se ferme-t-il pas et ne se termine-t-il pas?

51voto

Zanna Points 65764

Ctrl+C est le signal d'interruption. Lorsque vous tapez ceci dans un terminal, bash envoie SIGINT au travail en cours. S'il n'y a pas de travail (ce qui est le cas lorsque vous venez d'ouvrir un terminal), rien ne se passe. Le programme émulateur de terminal n'est pas un travail s'exécutant dans le shell, donc il ne reçoit pas le signal et ne se ferme pas.

Si vous voulez fermer le terminal avec une touche de contrôle, utilisez Ctrl+D (EOF) ce qui provoque la sortie de bash (et ferme aussi le terminal).

Voir aussi : <a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_01.html" rel="noreferrer">Le guide du débutant Bash sur les signaux</a> et de manière plus détaillée <a href="http://linusakesson.net/programming/tty/index.php" rel="noreferrer">Comment fonctionne la gestion des signaux</a>
note : cette réponse a été modifiée depuis la publication des commentaires

34voto

La combinaison de touches ^C, comme d'autres combinaisons de touches, n'est pas magique - elle envoie un code de touche au programme qui a le focus. (Dans X, le code de touche est 54 pour la touche C avec un modificateur de 0x4 pour Ctrl). Le programme qui reçoit le flux de touches est responsable de les traiter de manière appropriée - rappelez-vous que dans de nombreuses applications GUI, la combinaison de touches est copiée dans le presse-papiers.

Lorsqu'un émulateur de terminal GUI (par exemple, Konsole) ou un terminal virtuel reçoit une combinaison de touches qu'il interprète comme ^C, il peut faire l'une des trois choses suivantes. Si le terminal est en mode brut, alors le programme en cours d'exécution a demandé au terminal de ne pas effectuer de traitement de touches spéciales et de les transmettre directement au programme. Certains programmes qui prennent en charge des fonctionnalités avancées comme l'édition de ligne reçoivent les saisies clavier dans une configuration intermédiaire entre des saisies brutes complètes et des lignes de texte traitées; par exemple, bash reçoit les touches un par un. ^C est interprété par le terminal, mais la touche de retour en arrière est envoyée au shell telle quelle.

La plupart des programmes, cependant, utilisent le mode formé (car ce n'est pas brut), où le terminal interprète certaines touches de base avant de les envoyer réellement au programme (c'est pourquoi vous pouvez utiliser la touche de retour en arrière dans cat). Dans ce mode, le terminal lui-même traduit la combinaison de touches ^C en un signal SIGINT et l'envoie au processus enfant. Comme le terminal a généré le signal, il ne sera pas confus et ne se terminera pas.

  • SysRq est vraiment magique.

9voto

waltinator Points 32821

^C est généralement mappé (voir stty -a) sur le signal SIGINT (voir man 7 signal).

Un SIGINT non capturé interrompt le processus en cours, MAIS...

SIGINT est l'un des signaux pour lesquels un processus peut spécifier un comportement ("Capture d'un signal").

Ce que vous appelez "le terminal" capture SIGINT et reprend le travail.

7voto

Lorsque j'étais débutant, je ne savais pas que lorsque j'utilisais la ligne de commande, j'utilisais en fait deux programmes séparés, un terminal et un shell (par exemple bash).

Le shell est ce que vous connaissez probablement déjà, un programme qui prend en entrée des commandes ou des scripts, les exécute et affiche leur sortie.

Le terminal, d'autre part, est comme un intermédiaire entre l'utilisateur et un programme (ce programme est généralement un shell comme bash ou fish). Ce que fait le terminal, c'est lire l'entrée, par exemple du clavier, traiter cette entrée de différentes manières, et la rediriger vers l'autre programme (bash).

Cela fonctionne également dans l'autre sens, lorsque l'autre programme renvoie quelque chose, ce quelque chose est redirigé vers le terminal, puis c'est le travail du terminal de l'afficher à l'écran. Entre la réception de l'entrée et son affichage à l'écran, le terminal peut interpréter l'entrée de différentes manières.

Par exemple, si un programme renvoie la séquence suivante :

\e[0;31m some extra foobar text

Le terminal affichera à l'écran "some extra foobar text" en lettres rouges. Cela est dû au fait que le terminal choisit de traiter ce code étrange de manière spéciale ce qui lui indique d'afficher la sortie suivante en rouge.

De même, lorsque l'utilisateur appuie sur Ctrl - C, la seule chose spéciale à ce sujet est que le terminal choisit de le traiter de manière spéciale, il n'y a rien d'autre de spécial dans cette séquence de touches. En particulier, cela indique l'envoi du signal d'interruption (SIGINT) au processus qui s'exécute dans le terminal, c'est-à-dire le shell. À ce moment-là, si un programme a été lancé par le shell et s'exécute actuellement en premier plan, il reçoit également le signal. Le shell dispose alors d'un gestionnaire spécial pour ce signal et rien ne se passe. Mais la plupart des programmes ont des gestionnaires par défaut qui, dans le cas de SIGINT, se contentent de se fermer.

5voto

d a i s y Points 5143

Chaque signal a une action par défaut associée à celui-ci. L'action par défaut pour un signal est l'action qu'un script ou programme effectue lorsqu'il reçoit un signal.

Ctrl+C envoie le signal "interrupt" (SIGINT), qui par défaut termine le processus en cours d'exécution en premier plan.

Ctrl+D dit au terminal qu'il doit enregistrer un EOF sur l'entrée standard, que bash interprète comme un désir de sortir.

Un processus peut choisir d'ignorer le signal INT, et Bash le fait lorsque qu'il fonctionne en mode interactif.

À partir du manuel:

Quand bash est interactif, en l'absence de tout piège, il ignore SIGTERM (afin que kill 0 ne tue pas un shell interactif), et SIGINT est attrapé et géré (afin que la commande wait soit interruptible). Dans tous les cas, bash ignore SIGQUIT. Si la gestion des travaux est en effet, bash ignore SIGTTIN, SIGTTOU et SIGTSTP.


Comprenez-le avec trap:

trap est une fonction intégrée au shell qui répond aux signaux matériels et autres événements. Il définit et active des gestionnaires à exécuter lorsque le shell reçoit des signaux ou d'autres conditions spéciales.

trap [-lp] [arg] [sigspec …]

-l affiche une liste de noms de signaux et de leur correspondance numéros.
-p affiche les commandes trap associées à chacun des SIGNAUX_SPEC.

arg doit être lu et exécuté lorsque le shell reçoit le signal sigspec. Chaque sigspec est soit un nom de signal soit un numéro de signal. Les noms de signaux ne sont pas sensibles à la casse et le préfixe SIG est facultatif.

Si un sigspec est 0 ou EXIT, arg est exécuté lorsque le shell se ferme. Pour comprendre, fermez le terminal et ouvrez-le après avoir édité la ligne suivante dans le fichier .bashrc.

trap 'notify-send "Ctrl D pressed"' 0

Ctrl D est similaire à la commande exit pour sortir du terminal.

Si vous voulez que Bash quitte dès qu'il reçoit le signal INT, même en mode interactif, vous pouvez ajouter ce qui suit à votre ~/.bashrc:

trap 'exit' INT

ou

trap 'exit' 2

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X