Por que o Ctrl-C não mata o próprio Terminal?

36

O terminal está funcionando quando o abrimos.

[email protected]:/$

Acabei de abri-lo. Então, quando pressiono Ctrl + C , por que ele não se mata e fecha o terminal ??

    
por luv.preet 07.03.2017 / 18:35

5 respostas

43

Ctrl + C é o sinal de interrupção. Quando você digita isso em um terminal, o bash envia o SIGINT para o job em primeiro plano. Se não houver trabalho (quando você acabou de abrir um terminal), nada acontece. O programa emulador de terminal não é um trabalho em execução no shell, portanto, ele não recebe o sinal e não fecha.

Se você quiser fechar o terminal com uma tecla control, use Ctrl + D (EOF) que faz com que o bash saia (e feche o terminal também). / p>

Veja também: Guia de Bash para iniciantes sobre sinais e com mais profundidade Como funciona a manipulação de sinais
nota: esta resposta foi editada desde que os comentários foram postado

    
por Zanna 07.03.2017 / 18:47
31

O pressionamento de tecla ^ C , como outros pressionamentos de tecla *, não é mágico - ele envia um código de acesso para qualquer programa que tenha foco. (Em X, o código é 54 para o C com um modificador de 0x4 para Ctrl .) O programa que está recebendo o fluxo de chaves é responsável por fazer algo apropriado com eles Lembre-se que em muitos aplicativos GUI, o pressionamento de tecla copia para a área de transferência.

Quando um emulador de terminal GUI (por exemplo, Konsole) ou um terminal virtual recebe um pressionamento de tecla que ele interpreta como ^ C , ele pode fazer uma de três coisas. Se o terminal estiver em modo raw , o programa em execução pediu ao terminal para não executar qualquer qualquer manipulação de chaves especiais e passá-las diretamente para o programa. Alguns programas que suportam recursos avançados, como edição de linha, recebem entrada de teclado em alguma configuração entre pressionamentos de teclas brutos completos e linhas de texto processadas; bash , por exemplo, recebe pressionamentos de tecla um por vez. ^ C é interpretado pelo terminal, mas a tecla backspace é enviada para o shell no estado em que se encontra.

A maioria dos programas, no entanto, usa modo cozido (porque não é raw), onde o terminal interpreta algumas teclas básicas antes de realmente enviá-las ao programa (é por isso que você pode usar backspace em %código%). Neste modo, o próprio terminal traduz o pressionamento de tecla ^ C em um sinal cat e o envia para o processo filho. Como o terminal gerou o sinal, ele não ficará confuso e terminará.

  • O SysRq é realmente mágico.
por chrylis 07.03.2017 / 19:50
7

^ C é geralmente mapeado (veja stty -a ) para o sinal SIGINT (veja man 7 signal ).

Um SIGINT não detectado interrompe o processo em execução, MAS ...

SIGINT é um dos sinais que um processo pode especificar para o comportamento ("Captura de um sinal").

O que você chama de "terminal" captura SIGINT e volta ao trabalho.

    
por waltinator 07.03.2017 / 18:45
6

Quando eu era iniciante, estava faltando a parte que, quando eu estava usando a linha de comando, estava usando dois programas separados, um terminal e um shell (por exemplo, bash)

O shell é o que você provavelmente já sabe, um programa que recebe comandos ou scripts de entrada, os executa e imprime sua saída.

O terminal do outro lado é como um homem no meio entre o usuário e um programa (que geralmente é um shell como bash ou fish). O que o terminal faz é ler a entrada, por exemplo, do teclado, talvez processar essa entrada de alguma forma, e redirecioná-la para o outro programa (bash).

Além disso, isso funciona de outra forma também, quando o outro programa gera algo, que algo é redirecionado para o terminal, então é o trabalho do terminal produzir algo para a tela. Entre obtendo entrada e imprimindo isto à tela o terminal pode interpretar a entrada que está adquirindo de vários modos.

Por exemplo, se um programa gerar a seguinte sequência:

\e[0;31m some extra foobar text

O terminal emitirá para a tela "algum texto foobar extra" com letras de cor vermelha. Isso ocorre porque o terminal escolhe tratar o código estranho de uma maneira especial, código esse que indica a saída seguinte em vermelho.

Da mesma forma, quando o usuário pressiona Ctrl - C , a única coisa especial sobre isso é que o terminal escolhe tratá-lo de uma maneira especial, não há nada de especial nessa seqüência de teclas. Especificamente, isso sugere que ele enviou o sinal de interrupção (SIGINT) para o processo que está sendo executado dentro do terminal, que é o shell. Se, nesse momento, existir algum programa que tenha sido gerado pelo shell e estiver sendo executado no primeiro plano, ele também receberá o sinal. Agora o shell tem um manipulador especial para este sinal e nada acontece. Mas a maioria dos programas tem os manipuladores padrão que, no caso do SIGINT, simplesmente saem.

    
por user183833 07.03.2017 / 21:21
4

Cada sinal tem uma ação padrão associada a ele. A ação padrão para um sinal é a ação que um script ou programa executa quando recebe um sinal.

Ctrl + C envia o sinal de "interrupção" ( SIGINT ), cujo padrão é encerrar o processo para a tarefa em execução no primeiro plano .

Ctrl + D informa ao terminal que deve registrar um EOF na entrada padrão, que o bash interpreta como um desejo de sair .

Um processo pode optar por ignorar o sinal INT, e o Bash o faz quando está sendo executado no modo interativo.

Do manual :

  

Quando o bash é interativo, na ausência de armadilhas, ele ignora   SIGTERM (para que kill 0 não mate um shell interativo), e   SIGINT é capturado e manipulado (para que a espera embutida seja   interruptível). Em todos os casos, o bash ignora o SIGQUIT. Se o controle de trabalho for   com efeito, o bash ignora o SIGTTIN, o SIGTTOU e o SIGTSTP.

Entenda com armadilha :

armadilha é uma função incorporada ao shell que responde a sinais de hardware e outros eventos. Ele define e ativa os manipuladores a serem executados quando o shell recebe sinais ou outras condições especiais.

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

-l imprime uma lista de nomes de sinais e seus correspondentes   números.
-p exibe os comandos de trap associados a cada   SIGNAL_SPEC.

     

arg devem ser lidos e executados quando o shell receber sinal   sigspec. Cada sigspec é um nome de sinal ou um número de sinal.   Os nomes dos sinais são insensíveis a maiúsculas e o prefixo SIG é opcional.

Se um sigspec for 0 ou EXIT , o argumento arg é executado quando o shell é encerrado. Para entendê-lo, feche o terminal & amp; abra-o após editar a linha seguinte no arquivo .bashrc .

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

O Ctrl D é semelhante ao comando exit para sair do terminal.

Se você quiser que o Bash saia ao receber o sinal INT, mesmo no modo interativo, você pode adicionar o seguinte ao seu ~/.bashrc :

trap 'exit' INT

ou

trap 'exit' 2
    
por d a i s y 08.03.2017 / 16:05