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

39

Le terminal est en marche lorsque nous l'ouvrons.

luvpreet@DHARI-Inspiron-3542:/$

Je viens de l'ouvrir. Alors, quand j'appuie sur Ctrl+ C, pourquoi ne se tue-t-il pas et ne ferme-t-il pas le terminal?

luv.preet
la source
21
le terminal ne fonctionne pas dans le terminal ;-)
Pilot6
3
en ce qui concerne les travaux de contrôle pourquoi-d: unix.stackexchange.com/a/110248/14305
Janus Troelsen

Réponses:

48

Ctrl+ Cest le signal d'interruption. Lorsque vous tapez ceci dans un terminal, bash envoie SIGINT à la tâche au premier plan. S'il n'y a pas de travail (comme c'est le cas lorsque vous venez d'ouvrir un terminal), rien ne se passe. Le programme d'émulateur de terminal n'est pas un travail en cours d'exécution dans le shell. Il ne reçoit donc pas le signal et ne ferme pas.

Si vous souhaitez fermer le terminal avec une touche de contrôle, utilisez Ctrl+ D(EOF) pour que bash quitte (et ferme également le terminal).

Voir aussi: Guide du débutant Bash sur les signaux et plus en détail Fonctionnement de la gestion des signaux
note: cette réponse a été modifiée depuis la publication des commentaires.

Zanna
la source
4
Le terme approprié est que shell va "piéger" le signal. L'histoire est différente lorsque vous lancez une fenêtre de terminal à partir d'une autre fenêtre. L'envoi de ctrl + c à la fenêtre parent va tuer le processus enfant.
Sergiy Kolodyazhnyy
1
En outre, il est également possible d’indiquer aux fenêtres de l’interface graphique d’intercepter des signaux spécifiques provenant du serveur X11. C'est comme ça que vous pouvez avoir des popups vous informant du travail non sauvegardé, ou ouvrir des onglets comme dans les navigateurs
Sergiy Kolodyazhnyy
8
@chrylis le programme terminal envoie simplement le caractère ctrl-c, c’est en fait la couche noyau tty qui le transforme en signal.
Random832
3
@chrylis: Et le terminal, ou un programme y tournant - par exemple un éditeur de texte - pourrait bien traduire Ctl-C en une autre action.
jamesqf
3
Je ne pense pas que bashmettra fin aux programmes lorsque ctrl-c est enfoncé. Il indiquera simplement au noyau quel groupe de processus est actif et le noyau générera un signal à destination de ce groupe de processus lorsqu'il recevra ctrl-c du programme de terminal.
Kasperd
32

La ^Cfrappe, comme les autres frappes *, n'est pas magique: elle envoie un code d'activation au programme sélectionné. (Dans X, le code clé est 54 pour le Cavec un modificateur de 0x4 pour Ctrl.) Le programme qui reçoit le flot de clés est chargé de faire quelque chose qui leur convient - rappelez-vous que dans de nombreuses applications à interface graphique, la frappe est copiée dans le Presse-papiers.

Lorsqu'un émulateur de terminal graphique (par exemple, Konsole) ou un terminal virtuel reçoit une frappe qu'il interprète ^C, il peut effectuer l'une des trois choses suivantes. Si le terminal est en mode brut , le programme en cours d' exécution a demandé au terminal de ne pas effectuer une manipulation des touches spéciales lui - même et de les transmettre directement au programme. Certains programmes prenant en charge des fonctionnalités avancées telles que l'édition de lignes reçoivent une entrée au clavier dans une configuration donnée entre des frappes brutes complètes et des lignes de texte traitées; bash, par exemple, reçoit une frappe à la fois. ^Cest interprété par le terminal, mais la touche de retour arrière est envoyée telle quelle au shell.

Cependant, la plupart des programmes utilisent le mode cuit (car il n’est pas brut), où le terminal interprète quelques frappes de base avant de les envoyer au programme (c’est pourquoi vous pouvez utiliser le retour arrière cat). Dans ce mode, le terminal lui-même traduit la ^Cfrappe en un SIGINTsignal et l'envoie au processus enfant. Comme le terminal a généré le signal, il ne sera pas dérouté et ne se terminera pas.

  • SysRq est vraiment magique.
chrylis -on grève-
la source
De toute évidence, ce n’est pas super pertinent ici, mais pour l’informatique en général, il existe davantage de frappes magiques. Le plus célèbre, Ctrl+ Alt+ Deletedans le monde Windows, où la combinaison de touches est assez proche de la magie (il peut être utilisé pour faire fonctionner Windows, c'est assez magique en soi!), Car il est codé en dur dans le système pour interrompre et remplacer à peu près tout - assez semblable à SysRqdans ce sens.
Kryan
7
Bash n'utilise pas le mode brut - il utilise le mode caractère par caractère, c.-à-d. cbreak/ -icanon, Mais laisse le isigmode activé et reçoit des signaux réels lorsque vous appuyez sur les touches qui leur sont affectées. Il gère SIGINTen se comportant comme vous l'avez décrit (il n'annule pas uniquement l'édition de ligne, il annule également toute commande interne susceptible de s'exécuter en boucle), et ignore complètement SIGTSTPet SIGQUIT. D'autres programmes, tels que vi, ne le peuvent pas.
Random832
1
@KRyan Ctrl+ Alt+ Deleteétait encore plus magique qu'aujourd'hui - blogs.msdn.microsoft.com/oldnewthing/20140912-00/?p=44083 . Bien que je sois une personne Linux de cœur, je suis souvent très impressionné par la capacité de Windows à rendre les choses conviviales et logiques avec des ressources aussi limitées au début.
Muzer
Sur certains systèmes d’exploitation, même si un autre programme est ciblé, le système (gestionnaire de fenêtres, je suppose?) Obtient les pressions sur les touches avant l’émulateur de terminal. Si vous êtes en mesure de configurer des raccourcis clavier pour capturer des fenêtres, ouvrir des applications, déclencher des scripts, puis, avant d'envoyer les touches enfoncées à l'émulateur de terminal, elles sont vérifiées à la recherche des raccourcis que vous avez configurés. Et un autre exemple si vous n'avez aucune application ouverte ^cne tuera pas le gestionnaire de fenêtres :). Pas en mesure de commenter les personnages crus / cuits à la fois, mais la réponse est claire sur la façon dont cette frappe est SIGINT
Ajay
2
" mode cuit (car ce n'est pas cru)": Je suis ... sans voix. Après toutes ces années, je n'ai jamais établi le lien.
Isanae
8

^Cest généralement mappé (voir stty -a) sur le SIGINTsignal (voir man 7 signal).

Un non attrapé SIGINTinterrompt le processus en cours, MAIS ...

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

Ce que vous appelez "le terminal" attrape SIGINTet retourne au travail.

Waltinator
la source
7

Quand j'étais débutant, il me manquait la partie qui, lorsque j'utilisais la ligne de commande, j'utilisais en fait deux programmes distincts, un terminal et un shell (par exemple, bash)

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

Le terminal de l'autre côté est comme un homme au milieu entre l'utilisateur et un programme (programme qui est généralement une coquille comme bash ou poisson). Par exemple, le terminal lit les entrées au clavier, par exemple, peut-être les traiter d’une manière ou d’une autre et les rediriger vers un autre programme (bash).

Cela fonctionne aussi dans l'autre sens également, quand l'autre programme sort quelque chose, que quelque chose est redirigé vers le terminal, alors c'est le travail du terminal de sortir ce quelque chose à l'écran. Entre l’obtention d’une entrée et son impression à l’écran, le terminal peut interpréter l’entrée qu’il reçoit de différentes manières.

Par exemple, si un programme génère la séquence suivante:

\e[0;31m some extra foobar text

Le terminal affichera à l'écran "du texte supplémentaire" avec des lettres de couleur rouge. Cela est dû au fait que le terminal choisit de traiter ce code étrange d’une manière spéciale, ce qui l’indique de manière à imprimer la sortie suivante en rouge.

De même, lorsque l'utilisateur appuie Ctrl - Csur cette touche, la seule particularité de cette opération est que le terminal choisit de la traiter de manière spéciale. Cette séquence de touches n'a rien de spécial. Plus précisément, il est suggéré d'envoyer le signal d'interruption (SIGINT) au processus en cours d'exécution à l'intérieur du terminal, à savoir le shell. S'il existe à ce moment un programme créé par le shell et qui s'exécute au premier plan, il reçoit également le signal. Le shell a maintenant un gestionnaire spécial pour ce signal et rien ne se passe. Mais la plupart des programmes ont les gestionnaires par défaut qui, dans le cas de SIGINT, se terminent.

utilisateur183833
la source
5

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

Ctrl+ Cenvoie le signal "interruption" ( SIGINT ), qui par défaut met fin au processus pour le travail exécuté au premier plan.

Ctrl+ Dindique au terminal qu'il doit enregistrer un EOF sur une entrée standard, ce que bash interprète comme une volonté de quitter .

Un processus peut choisir d'ignorer le signal INT et Bash le fait lorsqu'il s'exécute en mode interactif.

Du manuel :

Lorsque bash est interactif, en l'absence de toute interruption, il ignore SIGTERM (pour que kill 0 ne tue pas un shell interactif), et SIGINT est capturé et traité (pour que l'attente intégrée soit interruptible). Dans tous les cas, bash ignore SIGQUIT. Si le contrôle de tâche est actif, bash ignore SIGTTIN, SIGTTOU et SIGTSTP.


Comprenez-le avec piège :

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

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

-l imprimer une liste de noms de signaux et leurs numéros correspondants.
-paffiche les commandes d'interruption associées à chaque SIGNAL_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 sigspec vaut 0 ou EXIT , arg est exécuté lorsque le shell se ferme. Pour le comprendre, fermez le terminal et ouvrez-le après avoir modifié la ligne suivante du .bashrcfichier.

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

Ctrl D est similaire à la exitcommande de sortie du terminal.

Si vous souhaitez que Bash quitte à la réception du signal INT, même en mode interactif, vous pouvez ajouter les éléments suivants à votre ~/.bashrc:

trap 'exit' INT

ou

trap 'exit' 2
Marguerite
la source
1
ça semble légitime !!
luv.preet