GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum gibt Linux beim Drücken von Strg+C immer ^C aus?

Es ist das Terminal (Treiber), das das ^C abfängt und es in ein Signal übersetzt, das an den angehängten Prozess (das ist die Shell) stty intr ^B gesendet wird würde den Terminaltreiber anweisen, stattdessen ein ^B abzufangen. Es ist auch der Terminaltreiber, der das ^C an das Terminal zurückgibt.

Die Shell ist nur ein Prozess, der sich am anderen Ende der Leitung befindet und seine stdin von Ihrem Terminal über den Terminaltreiber (z. B. /dev/ttyX) erhält, und seine stdout (und stderr) sind ebenfalls an dasselbe tty angehängt .

Beachten Sie, dass (wenn das Echo aktiviert ist) das Terminal die Tastenanschläge an beide sendet Prozess (Gruppe) und zurück zum Terminal. Der stty-Befehl ist nur ein Wrapper um die ioctl()s für den tty-Treiber für die Prozesse, die tty "steuern".

UPDATE:Um zu demonstrieren, dass die Shell nicht beteiligt ist, habe ich das folgende kleine Programm erstellt. Es sollte von seiner übergeordneten Shell über exec ./a.out ausgeführt werden (Es sieht so aus, als würde eine interaktive Shell sowieso eine Tochter-Shell forken.) Das Programm setzt den Schlüssel, der das SIGINTR erzeugt, auf ^B, schaltet das Echo aus und wartet dann auf die Eingabe von stdin.

#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

int thesignum = 0;
void handler(int signum);

void handler(int signum)
{ thesignum = signum;}

#define THE_KEY 2 /* ^B */

int main(void)
{
int rc;
struct termios mytermios;

rc = tcgetattr(0 , &mytermios);
printf("tcgetattr=%d\n", rc );

mytermios.c_cc[VINTR] = THE_KEY; /* set intr to ^B */
mytermios.c_lflag &= ~ECHO ; /* Dont echo */
rc = tcsetattr(0 , TCSANOW, &mytermios);
printf("tcsetattr(intr,%d) =%d\n", THE_KEY, rc );

printf("Setting handler()\n" );
signal(SIGINT, handler);

printf("entering pause()\n... type something followed by ^%c\n", '@'+THE_KEY );
rc = pause();
printf("Rc=%d: %d(%s), signum=%d\n", rc, errno , strerror(errno), thesignum );

// mytermios.c_cc[VINTR] = 3; /* reset intr to ^C */
mytermios.c_lflag |= ECHO ; /* Do echo */
rc = tcsetattr(0 , TCSANOW, &mytermios);
printf("tcsetattr(intr,%d) =%d\n", THE_KEY, rc );

return 0;
}

intr.sh:

#!/bin/sh
echo $$
exec ./a.out
echo I am back.

Die Shell wiederholt alles, was Sie eingeben, also wenn Sie ^C eingeben , auch das wird wiederholt (und in Ihrem Fall von Ihrem Signalhandler abgefangen). Der Befehl stty -echo abhängig von Ihren Bedürfnissen/Einschränkungen für Sie nützlich sein kann oder auch nicht, finden Sie weitere Informationen auf der Manpage für stty.

Natürlich passiert viel mehr auf einer niedrigeren Ebene, jederzeit Sie kommunizieren mit einem System über Peripheriegerätetreiber (z. B. den Tastaturtreiber, mit dem Sie das ^C-Signal erzeugen, und den Terminaltreiber, der alles anzeigt). Sie können noch tiefer in die Ebene der Assembler-/Maschinensprache, Register, Nachschlagetabellen usw. eintauchen. Wenn Sie ein detaillierteres, tiefgreifenderes Verständnis wünschen, sind die folgenden Bücher ein guter Ausgangspunkt:

Das Design des Unix-Betriebssystems ist eine gute Referenz für solche Dinge. Zwei weitere klassische Referenzen:Unix Programming Environment und Advanced Programming in the UNIX Environment

Schöne Zusammenfassung hier in dieser SO-Frage Wie beendet Strg-C einen untergeordneten Prozess?

"wenn Sie ein Programm ausführen, zum Beispiel find , die Schale:

  • der Shell-Fork selbst
  • und für das Kind die Standard-Signalbehandlung festlegen
  • ersetze das untergeordnete Element durch den angegebenen Befehl (z. B. durch find)
  • Wenn Sie STRG-C drücken, verarbeitet die übergeordnete Shell dieses Signal, aber die untergeordnete Shell erhält es - mit der Standardaktion - Terminierung. (das Kind kann auch die Signalverarbeitung implementieren)"

Linux
  1. So machen Sie Ihr Linux-Terminal und Ihre Shell weihnachtlich

  2. Wie gebe ich farbigen Text auf einem Linux-Terminal aus?

  3. Warum gibt pr_debug des Linux-Kernels keine Ausgabe aus?

  4. Warum ist Bash überall (in den meisten, wenn nicht allen Linux-Distributionen)?

  5. Warum sagen Linux-Leute immer, dass sie das Handbuch lesen sollen?

5 Möglichkeiten, Ihr Linux-Terminal aufzuteilen

Warum ich Alpine immer noch für E-Mail am Linux-Terminal liebe

Lolcat – Ein Befehlszeilentool zur Ausgabe von Rainbow Of Colors im Linux-Terminal

Bash-Skripting:So geben Sie Text in der Linux-Shell aus und formatieren ihn

ss - Ausgabeformat des Linux-Socket-Statistikdienstprogramms

Wie kann ich die Ausgabe einer Shell-Anwendung in Linux ausblenden?