GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo mostrar los caracteres de control (^c, ^d, ^[, …) de manera diferente en el Shell?

Cuando escribe caracteres de control en el shell, se muestran usando lo que se llama "notación de intercalación". Escape, por ejemplo, se escribe como ^[ en notación de intercalación.

Me gusta personalizar mi bash shell para que se vea genial. Por ejemplo, he cambiado mi PS1 y PS2 para volverse coloreado. Ahora quiero que los personajes de control también tengan una apariencia única para que se distingan más de los personajes normales.

$ # Here I type CTRL-C to abort the command.
$ blahblah^C
          ^^ I want these two characters to be displayed differently

¿Hay alguna manera de hacer que mi shell resalte los caracteres de control de manera diferente?

¿Es posible hacer que los muestre en negrita o tal vez hacer que aparezcan en colores diferentes al texto normal?

estoy usando bash shell aquí pero no etiqueté la pregunta con bash porque tal vez haya una solución que se aplique a muchas conchas diferentes.

Nota que no sé a qué nivel se lleva a cabo el resaltado de los caracteres de control. Primero pensé que estaba en el caparazón mismo. Ahora he oído que es readline que controla cómo son los caracteres de control en shells como bash . Entonces la pregunta ahora está etiquetada con readline y sigo buscando respuestas.

Respuesta aceptada:

Cuando presionas Ctrl+X , su emulador de terminal escribe el byte 0x18 en el lado maestro del par de pseudoterminales.

Lo que suceda a continuación depende de cómo esté configurada la disciplina de la línea tty (un módulo de software en el núcleo que se encuentra entre el lado maestro (bajo el control del emulador) y el lado esclavo (con el que interactúan las aplicaciones que se ejecutan en la terminal)). /P>

Un comando para configurar esa disciplina de línea tty es el stty comando.

Al ejecutar una aplicación tonta como cat que no conoce y no le importa si su stdin es un terminal o no, el terminal está en un canónico predeterminado modo en el que la disciplina de línea tty implementa un editor de línea rudimentario .

Algunas aplicaciones interactivas que necesitan más que ese tosco editor de líneas por lo general, cambie esas configuraciones al inicio y restáurelas al salir. Conchas modernas, en su indicación son ejemplos de tales aplicaciones. Implementan su propio editor de líneas más avanzado.

Por lo general, mientras ingresa una línea de comando, el shell pone la disciplina de línea tty en ese modo, y cuando presiona Intro para ejecutar el comando actual, el shell restaura el modo tty normal (como estaba en efecto antes de emitir el indicador).

Si ejecuta stty -a comando, verá la configuración actual en uso para las aplicaciones tontas . Es probable que veas el icanon , echo y echoctl la configuración está habilitada.

Lo que eso significa es que:

  • icanon :ese editor de líneas crudas está habilitado.
  • echo :los caracteres que escribe (que el emulador de terminal escribe en el lado maestro) se reproducen atrás (disponible para lectura por el emulador de terminal).
  • echoctl :en lugar de ser eco Así, los caracteres de control se hacen eco como ^X .

Entonces, digamos que escribes A B Retroceso-también conocido como Ctrl+H/? C Ctrl+X Retroceso Volver .

Su emulador de terminal enviará:ABbCx18br . La línea de disciplina hará eco atrás:ABb bC^Xb bb brn , y una aplicación que lee la entrada del lado esclavo (/dev/pts/x ) leerá ACn .

Todo lo que ve la aplicación es ACn , y solo cuando presione Enter por lo que no puede tener ningún control sobre la salida de ^X allí.

Relacionado:¿Cuál es la lectura del archivo conf entre el inicio de sesión y el shell sin inicio de sesión?

Notarás que para echo , el primer ^H (^? con algunos terminales, vea el erase ajuste) resultó en b b siendo enviado de vuelta a la terminal. Esa es la secuencia para mover el cursor hacia atrás, sobrescribir con espacio, mover el cursor hacia atrás nuevamente, mientras que el segundo ^H resultó en b bb b para borrar esos dos ^ y X personajes.

El ^X (0x18) se estaba traduciendo a ^ y X para la salida. Me gusta B , no llegó a la aplicación, ya que lo eliminamos con Retroceso.

r (también conocido como ^M ) fue traducido a rn (^M^J ) para eco, y n (^J ) para la aplicación.

Entonces, ¿cuáles son nuestras opciones para esos tontos aplicaciones:

  • deshabilitar echo (stty -echo ). Eso cambia efectivamente la forma en que se repiten los caracteres de control, al... no repetir nada. No es realmente una solución.
  • deshabilitar echoctl . Eso cambia la forma en que se controlan los caracteres (aparte de ^H , ^M … y todos los demás utilizados por el editor de línea) se repiten. Luego se repite como es. Es decir, por ejemplo, el carácter ESC se envía como e (^[ /0x1b ) byte (que el terminal reconoce como el comienzo de una secuencia de escape), ^G envías un a (un BEL, haciendo que su terminal emita un pitido)... No es una opción.
  • deshabilitar el editor de líneas crudas (stty -icanon ). No es realmente una opción, ya que las aplicaciones rudimentarias se volverían mucho menos útiles.
  • editar el código del kernel para cambiar el comportamiento de la disciplina de línea tty para que el echo de un carácter de control envía e[7m^Xe[m en lugar de solo ^X (aquí e[7m generalmente habilita el video inverso en la mayoría de los terminales).

Una opción podría ser usar un contenedor como rlwrap ese es un truco sucio para agregar un editor de líneas elegante a aplicaciones tontas. Ese contenedor en efecto intenta reemplazar el simple read() s desde el dispositivo terminal a llamadas al editor de línea readline (que sí cambian el modo de la disciplina de línea tty).

Yendo aún más lejos, incluso podría probar soluciones como esta que secuestra todas las entradas de la terminal para pasar por el editor de línea de zsh (que resalta ^X s en video inverso) confiando en :exec de la pantalla GNU función.

Ahora, para las aplicaciones que implementan su propio editor de líneas, depende de ellas decidir cómo echo está hecho. bash usa readline para aquello que no tiene ningún soporte para personalizar cómo se repiten los caracteres de control.

Para zsh , ver:

info --index-search='highlighting, special characters' zsh

zsh resalta los caracteres no imprimibles de forma predeterminada. Puede personalizar el resaltado con, por ejemplo:

zle_highlight=(special:fg=white,bg=red)

Para el resaltado en blanco sobre rojo de esos caracteres especiales.

Sin embargo, la representación de texto de esos caracteres no se puede personalizar.

En una configuración regional UTF-8, 0x18 se representará como ^X , u378 , U7fffffff (dos puntos de código Unicode no asignados) como <0378> , <7FFFFFFF> , u200b (un carácter Unicode no imprimible) como <200B> .

x80 en una configuración regional iso8859-1 se representaría como ^� …etc.


Linux
  1. ¿Cómo asignar la salida de un comando a una variable de shell?

  2. ¿Cómo detectar si el Shell está controlado desde Ssh?

  3. ¿Contar los caracteres de cada línea con Wc?

  4. Cómo hacer eco de una nueva línea en Bash Shell Scripts

  5. ¿Cómo convertir caracteres hexadecimales a ASCII en el shell de Linux?

Cómo limpiar sus datos en la línea de comando

Cómo cambiar el shell predeterminado en el sistema Linux

¿Cómo leer argumentos de línea de comando en scripts de Shell?

Cómo controlar versiones con Git en la línea de comando

Opción para mostrar caracteres de control en gedit

¿Cómo mostrar el contenido del archivo de forma recursiva?