GNU/Linux >> Znalost Linux >  >> Linux

Proč Linux vždy vypíše ^C po stisknutí Ctrl+C?

Je to terminál (ovladač), který zachytí ^C a převede jej na signál odeslaný připojenému procesu (což je shell) stty intr ^B by dal pokyn ovladači terminálu, aby místo toho zachytil ^B. Je to také ovladač terminálu, který vrací ^C zpět do terminálu.

Shell je jen proces, který sedí na druhém konci linky a přijímá svůj stdin z vašeho terminálu přes ovladač terminálu (jako /dev/ttyX) a jeho stdout (a stderr) jsou také připojeny ke stejnému tty .

Všimněte si, že (pokud je povolena ozvěna) terminál odesílá stisknuté klávesy oběma proces (skupinu) a zpět na terminál. Příkaz stty je pouze obalem kolem ioctl()s pro ovladač tty pro procesy "řídící" tty.

AKTUALIZACE:Abych demonstroval, že shell není zapojen, vytvořil jsem následující malý program. Měl by být spuštěn jeho nadřazeným shellem přes exec ./a.out (zdá se, že interaktivní shell rozvětví dceřiný shell, tak jako tak) Program nastaví klíč, který generuje SIGINTR, na ^B, vypne echo a poté čeká na vstup ze 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.

Shell opakuje vše, co napíšete, tedy když napíšete ^C , který se také odešle (a ve vašem případě zachytí váš obslužný program signálu). Příkaz stty -echo může nebo nemusí být pro vás užitečné v závislosti na vašich potřebách/omezeních, další informace naleznete v manuálové stránce stty.

Mnohem více se samozřejmě děje na nižší úrovni, kdykoli komunikujete se systémem prostřednictvím ovladačů periferních zařízení (jako je ovladač klávesnice, který používáte ke generování signálu ^C, a ovladač terminálu, který vše zobrazuje). Můžete se ponořit ještě hlouběji na úrovni jazyka assembleru/stroje, registrů, vyhledávacích tabulek atd. Pokud chcete podrobnější a hlubší úroveň porozumění, je dobré začít níže uvedené knihy:

Návrh operačního systému Unix je dobrou referencí pro tyto druhy věcí. Další dva klasické odkazy:Unixové programovací prostředí a pokročilé programování v UNIXovém prostředí

Pěkné shrnutí zde v této otázce SO Jak Ctrl-C ukončí podřízený proces?

"když spustíte program, například find , shell:

  • samotnou vidlici shellu
  • a pro dítě nastavit výchozí zpracování signálu
  • nahraďte dítě daným příkazem (např. find)
  • když stisknete CTRL-C, nadřazený shell tento signál zpracuje, ale podřízený jej přijme – s výchozí akcí – ukončí. (dítě může také implementovat zpracování signálu)"

Linux
  1. Jak převést výstup shellu Linuxu do HTML?

  2. Jak vytisknu barevný text do terminálu Linux?

  3. Proč pr_debug linuxového jádra nedává žádný výstup?

  1. Proč je Bash všude (ve většině, ne-li ve všech distribucích Linuxu)?

  2. Proč se Ctrl + V nevloží do Bash (Linux shell)?

  3. v linuxové konzoli, jak NEzabalit výstup

  1. Proč tento plášťový ropovod vystupuje?

  2. Vybarvěte konkrétní slova v terminálu Linux, kdykoli se objeví

  3. Jak mohu skrýt výstup shellové aplikace v Linuxu?