¿Qué hace CTRL + 4 (y CTRL + \) en bash?

22

Acabo de descubrir por accidente que CTRL+ 4 cierra los programas que leen la stdinentrada desde la línea de comandos.

Así es como se ve cuando escribo CTRL+ 4o CTRL+ / en los programas de lecturastdin

$ 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
$

Me ^\Quitmuestran y luego se cierra el programa. ¿Cuál es la diferencia de esto en comparación con el uso de ^Co ^D? ¿Qué ^\Quithacer?

Editar : Descubrí que CTRL+ \hace lo mismo.

wefwefa3
fuente

Respuestas:

37

Ctrl + 4 envía ^ \

Los terminales envían caracteres (o más precisamente bytes), no claves. Cuando se presiona una tecla que representa un carácter imprimible, el terminal envía ese carácter a la aplicación. La mayoría de las teclas de función están codificadas como secuencias de escape: secuencias de caracteres que comienzan con el número de carácter 27. Algunos teclados de la forma Ctrl+ character, y algunas teclas de función, se envían como caracteres de control, en el conjunto de caracteres ASCII , que todas las computadoras modernas utilizar como base (Unicode, ISO Latin- n, etc. son todos superconjuntos de ASCII), 33 caracteres son caracteres de control: caracteres del 0 al 31 y 127. Los caracteres de control no se pueden imprimir, pero tienen la intención de tener un efecto en las aplicaciones; por ejemplo, el carácter 10, que es Control-J (comúnmente escrito ^ J), es un carácter de nueva línea, por lo que cuando un terminal muestra ese carácter, mueve el cursor a la siguiente línea, en lugar de mostrar un glifo. El carácter de escape en sí es un carácter de control, ^ [(valor 27).

No hay suficientes caracteres de control para cubrir todos los Ctrl+ characterteclados. Solo las letras y los caracteres @[\]^_?tienen un carácter de control correspondiente. Cuando presiona Ctrl+ 4o Ctrl+ $(que supongo es Ctrl+ Shift+ 4), el terminal tiene que elegir algo para enviar. Dependiendo del terminal y su configuración, hay varias posibilidades comunes:

  • El terminal ignora el Ctrlmodificador y envía el carácter 4o $.
  • El terminal envía una secuencia de escape que codifica la tecla exacta y los modificadores que se presionaron.
  • El terminal envía algún otro carácter de control.

Muchos terminales envían caracteres de control para algunas teclas en la fila de dígitos:

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

No sé de dónde surgió esta convención en particular.

Ctrl+ |envía el mismo carácter porque es Ctrl+ Shift+ \y el terminal envía ^ \ tanto si se presionó la tecla Mayús como si no.

^ \ renuncia

El terminal en sí (más precisamente, el soporte de terminal genérico en el núcleo) interpreta algunos caracteres de control especialmente. Esta interpretación puede configurarse para mapear diferentes caracteres o puede ser desactivada por aplicaciones que desean procesar los caracteres por sí mismos. Una interpretación bien conocida es que ^ M, el carácter enviado por la Returntecla, envía la línea actual a la aplicación, si el terminal está en modo cocinado , en el que las aplicaciones reciben la entrada línea por línea.

Algunos caracteres envían señales a la aplicación en primer plano. ^ C envía la señal de interrupción (SIGINT), que convencionalmente le dice a la aplicación que pare lo que está haciendo y lea el siguiente comando del usuario. Las aplicaciones no interactivas suelen salir. ^ \ envía la señal de salida (SIGQUIT), que convencionalmente le dice a la aplicación que salga lo antes posible sin guardar nada; muchas aplicaciones no anulan el comportamiento predeterminado, que es matar la aplicación de inmediato¹. Entonces, cuando presiona Ctrl+ 4(o cualquier cosa que envíe el carácter ^ \) en cato bc, ninguno de los cuales anula el comportamiento predeterminado, la aplicación se cierra.

El terminal en sí imprime la ^\parte del mensaje: es una representación visual del carácter que escribió, y el terminal está en modo cocinado y con eco activado (el terminal muestra los caracteres tan pronto como los escribe, en lugar de modo sin eco donde los caracteres solo se envían a la aplicación, que puede o no elegir mostrarlos). La Quitparte proviene de bash: se da cuenta de que su proceso hijo murió por una señal de abandono, y esa es su forma de avisarle.

Los shells manejan todas las señales comunes, de modo que si escribe ^ \ en un shell, no cancela su sesión, solo obtiene un nuevo aviso, igual que ^ C.

Puedes jugar con la configuración del terminal con el sttycomando.

¹ Y tradicionalmente genera un volcado de núcleo , pero muchos sistemas lo deshabilitan por defecto en la actualidad.

Gilles 'SO- deja de ser malvado'
fuente
SIGINT mata al grupo de procesos en primer plano y SIGQUIT lo mata con un volcado de núcleo. Ambas señales pueden ser manejadas. No estoy seguro de lo que quieres decir con leer el siguiente comando . Los sistemas no deshabilitan los volcados de núcleo más allá de establecer el límite de tamaño de núcleo inicial a 0 (no el difícil, generalmente es libre de aumentarlo).
Stéphane Chazelas
@ StéphaneChazelas En un programa que realiza interacciones con el usuario, la semántica habitual de SIGINT es cancelar el comando de usuario actual y permitir que el usuario interactúe con el programa, es decir, volver al bucle de comando principal. Por otro lado, no recuerdo haber visto un programa en el que SIGQUIT no se cierra (salvo errores en el controlador de señal). De hecho, la forma en que muchos sistemas deshabilitan los volcados de núcleo de forma predeterminada es establecer el límite flexible del tamaño de volcado de núcleo en 0, dejando a los usuarios libres de cambiar esta configuración predeterminada si lo desean.
Gilles 'SO- deja de ser malvado'
Esa es la excepción. SIGINT mata la tarea actualmente en ejecución. Solo unas pocas aplicaciones ampliarían eso para matar su propia tarea "en primer plano". Debes estar pensando en lesso vim. Tenga en cuenta que cmd | less, en CTRL-Cgeneral, mata cmd(mientras lessse maneja para cancelar la acción actual (como una búsqueda)) (continuación)
Stéphane Chazelas
La redacción de su respuesta me parece confusa a ese respecto. El hecho de que SIGQUIT generalmente no se maneja es que no se usa de la misma manera. Presiona CTRL-C para cancelar lo que está haciendo actualmente. Usaría `CTRL- \` solo ocasionalmente para depurar y generar un volcado de memoria. Por lo general, no hay ninguna razón por la que una aplicación quiera interponerse en su camino tratando de hacerlo.
Stéphane Chazelas
@ StéphaneChazelas No solo menos y vim, la mayoría de las aplicaciones basadas en terminales que leen los comandos del usuario a eso. Por ejemplo REPL (bash, dash, ksh, zsh, python, irb, fsharpi, Mathematica, ...). No es raro. Su primer comentario se opone a pintar SIGINT y SIGQUIT como demasiado diferente y su último comentario se opone a pintar SIGINT y SIGQUIT como demasiado similar, lo que me deja desconcertado sobre lo que está conduciendo.
Gilles 'SO- deja de ser malvado'
7

Además de la respuesta de Gilles, permítanme agregar que siempre pueden ingresar caracteres no imprimibles en bash con Ctrl-v+ key( Ctrl-v+ Ctrl+4en este caso) y verificar el código de caracteres con

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

obtienes el código decimal del carácter, que como puedes comprobar man asciicorresponde al separador de archivos (FS) .

jimmij
fuente
Entonces, ¿qué hace ctrl + v? Estoy acostumbrado a que sea "pegar portapapeles".
JDługosz
2
@ JDługosz: Ctrl-V le dice a la terminal que no interprete el siguiente carácter. Es un hecho desafortunado que las combinaciones de teclas GUI se hayan apoderado de esos caracteres de control, causando confusión innecesaria. Solía ​​ser que Linux usaba Alt- [Clave] para las teclas GUI (por ejemplo, Alt-C / Alt / V para copiar / pegar), pero obviamente la gente pensaba que hacer lo mismo que Windows era más importante; mientras tanto, los usuarios de Mac todavía no tienen problemas para usar la tecla Comando en lugar de la tecla Ctrl para esas operaciones.
celtschk
El comando (más corto) es printf '%d\n' '"^\':?
Isaac