Detectar mediante programación el código de escape ANSI admitido por el terminal

Detectar mediante programación el código de escape ANSI admitido por el terminal

Estoy jugando con scripts de shell que usan códigos ANSI y descubrí que, por una razón u otra, se admiten diferentes códigos de escape según su terminal/sistema operativo.

En algunos casos, recibo inesperadamente un volcado de basura sin analizar, lo que supongo significa que mi terminal (en Mac OS) no admite el código de escape utilizado, a pesar de haber leído en varios lugares que significan lo mismo:

27 = 033 = 0x1b = ^[ = \e

Al buscar encontréesta pregunta sobre la detección de soporte de escape de barra.

La respuesta seleccionada huele el $TERMvalor a detectar.

case $TERM in
  (|color(|?))(([Ekx]|dt|(ai|n)x)term|rxvt|screen*)*)
    PS1=$'\e\]0;$GENERATED_WINDOW_TITLE\a'"$PS1"
esac

Pero me pregunto qué tan confiable es eso.

¿Existe una forma estándar de verificar la compatibilidad con el código de escape (principalmente para Bash), o ese script es prácticamente el más común?

  • Alternativamente, ¿qué código de escape puedo utilizar para "garantizar" el soporte más amplio?
  • ¿Qué pasa con la expansión del eco -e?
  • ¿Cuáles son las mejores prácticas generales en términos de portabilidad/disponibilidad/distribución paraguionesque utilizan o hacen referencia a códigos de control?

Esto esuna buena lectura tambiénpara cualquiera que busque información.

Respuesta1

¿Tiene operaciones específicas en mente?

A continuación se muestra un ejemplo de usomodo destacado, que en muchos terminales dará un resultado visible y fuerte:

tput smso; echo hello, world; tput rmso

La tputherramienta utiliza el valor de la $TERMvariable de entorno para determinar qué secuencias de escape generar, si corresponde. Por ejemplo

TERM=xterm
( tput smso; echo hello, world; tput rmso ) | hexdump -C
00000000  1b 5b 37 6d 68 65 6c 6c  6f 2c 20 77 6f 72 6c 64  |.[7mhello, world|
00000010  0a 1b 5b 32 37 6d                                 |..[27m|

TERM=dumb
( tput smso; echo hello, world; tput rmso ) | hexdump -C
00000000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a           |hello, world.|

Interesantes pares de características se pueden encontrar enman 5 terminfo, algunos de los cuales son los siguientes:

  • Destacado: smsoyrmso
  • Subrayado: smulyrmul
  • Parpadea (¡sí!):blink
  • Doble ancho: swidmyrwidm
  • Contrarrestar:rev
  • Cancelalo todo:sgr0

Si desea escribir texto en negrita, pero sólo si el terminal lo entiende, entonces un fragmento como este funcionará

boldOn=$(tput smso)
boldOff=$(tput rmso)
# ...
printf "%s%s%s\n" "$boldOn" 'This message will be in bold, when available' "$boldOff"

Respuesta2

De hecho, es posible consultar a los terminales DEC (y sus clones y emulaciones, incluido xterm) sobre sus capacidades; simplemente no sobre el soporte de secuencias de escape individuales (o su integridad). UNIX generalmente no usa esta característica, confiando en bases de datos termcap/terminfo (que también documentan las peculiaridades).

Como referencia, las secuencias son DA ("Atributos del dispositivo", estándar ANSI) y DECID ("Identificar terminal", DEC privado).

información relacionada