macos - informatica - ¿Se puede hacer que Terminal.app respete los códigos de escape de ANSI?
que es el codigo ansi en informatica (1)
Observé que con la variable de entorno TERM
configurada en xterm
o xterm-256color
la utilidad Terminal.app de Mac OS X respeta la mayoría de los códigos de escape ANSI, al menos cuando esos códigos de escape pertenecen al cambio de color del texto.
Por ejemplo:
echo -e "/033[0;31mERROR:/033[0m It worked"
Produce:
Sin embargo, estoy más interesado en la funcionalidad de manipulación de ubicación del cursor que ofrecen los códigos de escape de ANSI. Desafortunadamente, ese tipo de código no parece funcionar demasiado bien en Terminal.app, por lo que he podido reunir. Por ejemplo, lo que quiero hacer es algo como esto:
echo -e "/033[sHello world/033[uG''day"
ESC[s
Guarda la posición actual del cursor, mientras que ESC[u
restaura la última posición guardada. Como resultado de ejecutar el script anterior, esperaría que los cinco caracteres en "G''day" sobrescriban los cinco caracteres de "Hola" después de que el cursor se haya reposicionado, produciendo lo siguiente:
G''day world
De hecho, esto es exactamente lo que obtengo con iTerm2.app, ConEmu para Windows (ejecutando MinGW o la copia de MSYS Git de bash.exe), etc. Lo que veo en Terminal.app, sin embargo, es este:
Hello worldG''day
¿Hay alguna razón para esto, aparte de Terminal.app simplemente careciendo de soporte para estos códigos? ¿Hay alguna manera de habilitar esta funcionalidad? ¿Hay alguna posibilidad de que tenga algo mal configurado? Mi configuración de TERMINO? ¿Algo más?
He estado buscando en todas partes, pero no he encontrado nada relevante para Terminal.app, específicamente. Me parece extraño que sea compatible con texto en color a través de códigos de escape ANSI, pero no con el reposicionamiento del cursor mediante la misma tecnología. Parece un subconjunto bastante arbitrario de un estándar bastante bien definido. Eso es lo que me hace pensar que tengo algo mal configurado, en lugar de Terminal.app es el culpable ... pero, supongo que es posible que simplemente no se pueda hacer. (¿Probablemente uno de los motivos por los que iTerm2 existe en primer lugar?)
Si alguien pudiera arrojar algo de luz sobre esta situación, ¡sería muy apreciado!
ACTUALIZAR
Entonces, he hecho un poco más de lectura y experimentación, y descubrí la siguiente rareza:
Después de analizar la respuesta de nm a continuación, decidí escribir los bytes que se devolvían por tput
a un archivo para ver cómo diferían de las instrucciones ANSI normales.
$ echo "$(tput sc)Hello world$(tput rc)G''day" > out.bin
$ cat -e out.bin
^[7Hello world^[8G''day$
Parece que todo funciona como se espera si le envío las secuencias ESC
7
y ESC
8
, pero NO si lo envío ESC
[s
y ESC
[u
, que según entiendo son la representación más típica de los códigos ANSI SCP y RCP (Guarde la posición del cursor y restaure la posición del cursor, respectivamente). Dado que poner caracteres decimales ASCII 7
u 8
junto a una representación de byte octal escapado es imposible ( /0337
! = ESC
), las variables de entorno se pueden usar en su lugar para evitar depender de la tput
:
$ esc=$''/033''
$ csi="${esc}["
$ echo "${csi}0;31mERROR:${csi}0m It worked."
ERROR: It worked. # Color works, as before
$ echo "${csi}sHello world${csi}uG''day"
Hello worldG''day # No dice
$ echo "${esc}7Hello world${esc}8G''day"
G''day world # Success
No estoy seguro de por qué es esto. Si ESC
7
y ESC
8
son algún tipo de código propietario o personalizado para ANSI SCP y RCP que tiene el potencial de variar desde la implementación del terminal hasta la implementación del terminal, esto me explicaría por qué se creó el tput
en primer lugar.
Lamentablemente, no puedo usar la tput
para lo que estoy trabajando actualmente, ya que no estoy trabajando exclusivamente en un entorno de bash. Tengo más curiosidad sobre cómo se interpretan los bytes crudos de terminal a terminal, y más específicamente, si hay o no una manera de hacer que Terminal.app respete los mismos códigos de escape ANSI que todos los demás emuladores de terminal que he probado parece no tener ningún problema con. ¿Es eso posible? En este punto, estoy empezando a pensar que simplemente podría no serlo, lo cual está bien, pero sería bueno saberlo con certeza, y posiblemente también aprender la razón por la cual.
No use códigos ANSI. Use técnicas apropiadas basadas en terminfo. Los terminales basados en Xterm no están especificados para admitir todos los códigos ANSI. Algunos lo hacen por compatibilidad, otros no.
La secuencia de guardar posición de cursor viene dada por el comando tput sc
y la posición del cursor de restauración es tput rc
.
echo -e "$(tput sc)Hello world$(tput rc)G''day"
debería funcionar en cualquier terminal que admita estas secuencias.
Para ver una representación legible de las secuencias compatibles, use el comando infocmp
. La salida puede ser bastante larga. Si está interesado en sc
y rc
:
infocmp | grep --color '' [sr]c=''
Descargo de responsabilidad: probado en mi máquina Linux, no tengo una Mac cerca.
ACTUALIZAR
Terminal.app se modela después de que xterm y xterm se modelen después del terminal VT100. VT100 no implementó CSI s
secuencias CSI u
y CSI s
, pero usó secuencias DEC privadas de ESC 7
y ESC 8
(fuente) . Los modelos de TV posteriores respaldaron tanto CSI s/u
como ESC 7/8
, bajo diferentes nombres y con una funcionalidad ligeramente diferente (fuente) .
ECMA 48 no parece especificar ninguna secuencia de posición de cursor de guardar / restaurar (fuente (PDF)) , o no pude encontrarlos allí. No sé de dónde proviene CSU s/u
. Su nombre en la documentación de VT510 sugiere que de alguna manera están conectados con SCO. Esta fuente sugiere que en realidad son secuencias privadas sin significado estándar. Los terminales SUN usan SCI s
para hacer un reinicio. Probablemente sea un error etiquetar estas dos secuencias ANSI.
Las versiones modernas de xterm y otros programas de terminal X11 (konsole, rxvt ...) son compatibles con ESC 7/8
y CSI s/u
, pero la base de datos terminfo solo anuncia ESC 7/8
. Terminal.app aparentemente solo es compatible con ESC 7/8
.