O que CTRL + 4 (e CTRL + \) faz no bash?

22

Acabei de descobrir por acidente que CTRL+ 4 fecha os programas que lêem stdinentrada da linha de comando.

É assim que aparece quando digito CTRL+ 4ou CTRL+ / em programas que lêemstdin

$ cat
wefwef
wefwef
^\Quit
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
^\Quit
$

Eu sou ^\Quitexibido e o programa é fechado. Qual é a diferença disso em comparação com o uso de ^Cou ^D? O que ^\Quitfaz?

Edit : Descobriu que CTRL+ \faz a mesma coisa.

wefwefa3
fonte

Respostas:

37

Ctrl + 4 envia ^ \

Os terminais enviam caracteres (ou mais precisamente bytes), não chaves. Quando uma tecla que representa um caractere imprimível é pressionada, o terminal envia esse caractere para o aplicativo. A maioria das teclas de função é codificada como seqüências de escape: sequências de caracteres que começam com o número de caractere 27. Alguns acordes de teclas do formulário Ctrl+ charactere algumas teclas de função são enviados como caracteres de controle - no conjunto de caracteres ASCII , que todos os computadores modernos usar-se como uma base (Unicode, ISO latino n, etc. são todos os superconjuntos de ASCII), 33 caracteres são caracteres de controle: caracteres número 0 a 31 e 127. Os caracteres de controle não são imprimíveis, mas devem ter efeito nos aplicativos; por exemplo, o caractere 10, que é Control-J (geralmente escrito ^ J), é um caractere de nova linha; portanto, quando um terminal exibe esse caractere, ele move o cursor para a próxima linha, em vez de exibir um glifo. O caractere de escape em si é um caractere de controle, ^ [(valor 27).

Não há caracteres de controle suficientes para cobrir todos os Ctrl+ characterteclados. Somente letras e caracteres @[\]^_?têm um caractere de controle correspondente. Quando você pressiona Ctrl+ 4ou Ctrl+ $(que eu presumo é Ctrl+ Shift+ 4), o terminal precisa escolher algo para enviar. Dependendo do terminal e sua configuração, existem várias possibilidades comuns:

  • O terminal ignora o Ctrlmodificador e envia o caractere 4ou $.
  • O terminal envia uma sequência de escape que codifica a tecla exata e os modificadores que foram pressionados.
  • O terminal envia algum outro caractere de controle.

Muitos terminais enviam caracteres de controle para algumas teclas na linha de dígitos:

  • Ctrl+ 2→ ^ @
  • Ctrl+ 3→ ^ [
  • Ctrl+ 4→ ^ \
  • Ctrl+ 5→ ^]
  • Ctrl+ 6→ ^^
  • Ctrl+ 7→ ^ _
  • Ctrl+ 8→ ^?

Não sei onde surgiu essa convenção em particular.

Ctrl+ |envia o mesmo caractere porque é Ctrl+ Shift+ \e o terminal envia ^ \ se a tecla shift foi pressionada ou não.

^ \ encerra

O próprio terminal (mais precisamente, o suporte genérico ao terminal no kernel) interpreta alguns caracteres de controle especialmente. Essa interpretação pode ser configurada para mapear caracteres diferentes ou desativada por aplicativos que desejam processar os caracteres sozinhos. Uma interpretação bem conhecida é que ^ M, o caractere enviado pela Returntecla, envia a linha atual para a aplicação, se o terminal estiver no modo cozido , no qual as aplicações recebem entrada linha por linha.

Alguns caracteres enviam sinais para o aplicativo em primeiro plano. ^ C envia o sinal de interrupção (SIGINT), que instrui o aplicativo a interromper o que está fazendo e ler o próximo comando do usuário. Aplicativos não interativos geralmente saem. ^ \ envia o sinal de abandono (SIGQUIT), que normalmente instrui o aplicativo a sair o mais rápido possível sem salvar nada; muitos aplicativos não substituem o comportamento padrão, que é matar o aplicativo imediatamente¹. Portanto, quando você pressiona Ctrl+ 4(ou qualquer coisa que envie o caractere ^ \) em catou bc, nenhum dos quais substitui o comportamento padrão, o aplicativo é eliminado.

O próprio terminal imprime a ^\parte da mensagem: é uma representação visual do caractere que você digitou e o terminal está no modo de cozimento e com o eco ativado (os caracteres são exibidos pelo terminal assim que você os digita, em oposição a modo não eco, onde os caracteres são enviados apenas para o aplicativo, que pode ou não optar por exibi-los). A Quitparte vem do bash: percebe que o processo filho morreu de um sinal de parada, e essa é a maneira de informar você.

Os shells lidam com todos os sinais comuns, de modo que, se você digitar ^ \ em um shell, não encerra sua sessão, apenas recebe um novo prompt, o mesmo que ^ C.

Você pode jogar com as configurações do terminal com o sttycomando

¹ E tradicionalmente gere um dump principal , mas muitos sistemas o desativam por padrão hoje em dia.

Gilles 'SO- parar de ser mau'
fonte
O SIGINT mata o grupo de processos em primeiro plano e o SIGQUIT o mata com um dump principal. Ambos os sinais podem ser manipulados. Não sei o que você quer dizer com ler o próximo comando . Os sistemas não desabilitam os dumps principais, a não ser configurando o limite inicial de tamanho do coletor para 0 (não o difícil, geralmente você pode aumentá-lo).
Stéphane Chazelas
@ StéphaneChazelas Num programa que realiza interações com o usuário, a semântica usual do SIGINT é cancelar o comando do usuário atual e permitir que o usuário interaja com o programa, ou seja, volte ao loop de comando principal. Por outro lado, não me lembro de ver um programa em que o SIGQUIT não é encerrado (salvo erros no manipulador de sinais). De fato, a maneira como muitos sistemas desativam os core dumps por padrão é definir o limite flexível do tamanho do core dump como 0, deixando os usuários livres para alterar essa configuração padrão, se desejarem.
Gilles 'SO- stop be evil' -
Essa é a exceção. O SIGINT mata a tarefa atualmente em execução. Apenas alguns aplicativos estenderiam isso para matar sua própria tarefa "em primeiro plano". Você deve estar pensando em lessou vim. Note que no cmd | less, CTRL-Cque geralmente matar cmd(enquanto que para lessele é tratado para cancelar a ação atual (como uma pesquisa)) (continua)
Stéphane Chazelas
Acho a redação da sua resposta confusa a esse respeito. O fato de SIGQUIT geralmente não ser tratado é que não está sendo usado da mesma maneira. Você pressiona CTRL-C para abortar o que está fazendo no momento. Você usaria `CTRL- \` apenas ocasionalmente para depuração para gerar um dump principal. Geralmente, não há razão para que um aplicativo queira atrapalhar o processo.
Stéphane Chazelas
@ StéphaneChazelas Não apenas menos e vim, a maioria dos aplicativos baseados em terminal que lêem comandos do usuário para isso. Por exemplo, REPL (bash, dash, ksh, zsh, python, irb, fsharpi, Mathematica,…). Não é incomum. Seu primeiro comentário objeta a pintar SIGINT e SIGQUIT como muito diferente e o seu último comentário objeta a pintar SIGINT e SIGQUIT como muito semelhante, o que me deixa perplexo com o que você está dirigindo.
Gilles 'SO- stop be evil' -
7

Além da resposta de Gilles, deixe-me acrescentar que você sempre pode inserir caracteres não imprimíveis no bash com Ctrl-v+ key( Ctrl-v+ Ctrl+4neste caso) e verificar o código de caractere com

$ printf '^\' | od -An -tu    # input ^\ as C-v C-4
28

você obtém o código decimal do caractere que, como você pode fazer o check-in, man asciicorresponde ao separador de arquivos (FS) .

jimmij
fonte
Então, o que ctrl + v faz? Estou acostumado a isso "colar área de transferência".
JDługosz
2
@ JDługosz: Ctrl-V diz ao terminal para não interpretar o seguinte caractere. É um fato lamentável que as combinações de teclas da GUI tenham assumido esses caracteres de controle, causando confusão desnecessária. Antes, o Linux usava Alt- [Key] para as teclas da GUI (por exemplo, Alt-C / Alt / V para copiar / colar), mas as pessoas obviamente pensavam que fazer o mesmo que o Windows era mais importante; enquanto isso, os usuários de Mac ainda não têm problemas para usar a tecla Command em vez da tecla Ctrl para essas operações.
Celtschk 30/08/2015
O comando (mais curto) é printf '%d\n' '"^\':?
Isaac