Otras lecturas

Otras lecturas

Cuando ejecuta cal en Linux, la salida del mes actual resaltará el video inverso del día actual. Cuando envío esa salida a hexdump -c, obtengo algunos resultados interesantes:

0000000               N   o   v   e   m   b   e   r       2   0   1   6
0000010                          \n   S   u       M   o       T   u    
0000020   W   e       T   h       F   r       S   a          \n        
0000030                       1           2       _  \b       _  \b   3
0000040           4           5          \n       6           7        
0000050   8           9       1   0       1   1       1   2          \n
0000060   1   3       1   4       1   5       1   6       1   7       1
0000070   8       1   9          \n   2   0       2   1       2   2    
0000080   2   3       2   4       2   5       2   6          \n   2   7
0000090       2   8       2   9       3   0                            
00000a0                  \n                                            
00000b0                                              \n                
00000bc

Como puede ver, se está imprimiendo una secuencia invisible de _\b _\b antes del '3' que está resaltado para hoy. _ siendo guión bajo (5F en ASCII hexadecimal) y \b siendo Ctrl-H o 08 en ASCII hexadecimal. ¿Qué es esto? Sé que hay muchos códigos de terminal oscuros, pero esperaría que usara algo más estándar como \e[7m. Lo que es aún más extraño es que no puedo reproducir el mismo comportamiento de cal imprimiendo los mismos caracteres usando funciones printf estándar como uno de estos comandos:

/usr/bin/printf "1 2 _\b _\b3 4 5\n"
/usr/bin/printf "1 2 _^H _^H3 4 5\n"

Donde ^H se crea presionando Ctrl-V Ctrl-H. Pero ninguno de estos produce la misma salida de video inversa que produce cal. Incluso intenté escribir un pequeño programa en C para hacerlo también. También lo intenté con echo -e. Lo interesante es que si bien no invierte el video en la terminal, si canalizo la salida desde less -R, cambia su color a amarillo y lo subraya. En otros terminales lo probé solo lo subraya. Casi parece exagerado, pero si uso un carácter distinto de _ no funciona, lo que me hace pensar que _\b es una secuencia de código única. ¿Y cómo se invierte el vídeo de ese personaje?

¿Alguna idea de esto?

La página de manual dice que se supone que la salida de cal es una versión compatible bit por bit con el comando cal original de Unix. Así que sólo puedo asumir que se trata de algún código antiguo.

Respuesta1

Casi parece demasiado llamativo.

Eso es exactamente lo que es. Como se discutió en¿Por qué hay 11 tabulaciones en una consola de 80 columnas?, ayuda pensar en la acción de las máquinas de escribir mecánicas cuando se trata de terminales Unix. En este caso, la secuencia _ BS (el carácter de retroceso) antes de un carácter es una convención que se utiliza para indicar el subrayado de ese carácter, porque en algunos terminales así es como se subraya el texto. Una secuencia de control alternativa es BS _después del personaje. En los terminales originales no importaba qué sobrepasaba a qué, por supuesto. En los terminales de vídeo contemporáneos, el último carácter que se escribe “gana”, borrando los datos anteriores. Por lo tanto, la _ BS <personaje>Se prefiere el orden.

FreeBSD ncal, que es lo que es este programa, tiene dos modos de funcionamiento a la hora de resaltar.

  • Si su salida es una terminal, busca las secuencias soy separa el tipo de terminal actual en la base de datos termcap y las emite a ambos lados del texto resaltado. (En realidad, hay un error en el código que hace esto, que tiene que ver con un buffer en la pila que queda fuera de alcance y su contenido se usa más tarde, que nadie parece haber detectado).
  • Si su salida no es un terminal, emite el texto con cada carácter a resaltar precedido por una _secuencia BS.

No puede replicar esto emitiendo una _secuencia BS a su terminal, a menos (por supuesto) que su terminal sea uno de los terminales donde así es como se subrayan las cosas. Este no es el caso de los emuladores de terminal, y casi con seguridad no es el caso de cualquier terminal o emulador de terminal que esté utilizando aquí.

Puedes, sin embargo,filtrartexto que usa esta convención, a través del ulprograma, que reconoce esta y varias otras convenciones similares a las de las máquinas de escribir y las traduce a cualesquiera que sean las secuencias de control para la terminal, buscándolas en la base de datos termcap. También puede filtrar las salidas de sus printfcomandos a través de ul.

En otros terminales lo probé solo lo subraya.

Irónicamente, filtrar la salida en modo no terminal a ncaltravés del ulprograma es de hecho ligeramente superior a permitir ncalescribir las secuencias de control del terminal. Mientras que ncalutiliza el terminaldestacarmodo, ulintentará utilizar la configuración real del terminal.subrayarmodo (si lo tiene) al traducir la _secuencia BS. Como explica el manual de termcap, el modo destacado puede ser cualquiera que sea adecuado para el terminal (incluyendo negrita, video inverso o colores) y no necesariamente está subrayado. En uno de tus terminales se ve claramente una combinación de subrayado y cambio de color.

Además, ultambién funciona con terminales que no tienen secuencias de inicio/fin de subrayado, pero que sí tienen secuencias de último carácter subrayado. Irónicamente, ulse las arreglará si su terminalrealmente esuno que destaca por tener BS _después de cada personaje, mientras que ncalno da abasto.

Y, por supuesto, ulno tiene ncalel error de manejo del búfer. ☺

Si canalizo la salida a less -R, cambia su color a amarillo y la subraya.

Como habrás notado, el lessprograma entiende _las secuencias BS y las maneja de manera similar a como ullo hace el programa. No es completamente lo mismo. ulpuede manejar secuencias que involucran múltiples _caracteres y BS, y también puede manejar secuencias similares en negrita. lessno puedo. Compara lo que ves en estos dos:

  • /usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4. \b\b\b45 6\n" | ul
  • /usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4. \b\b\b45 6\n" | menos

en los buenos viejos tiempos

Lamentablemente, estos todavía son "los buenos viejos tiempos". No dejes que la gente te engañe haciéndote creer que esto rara vez se usa hoy en día.

No está en el manual, pero el código fuente ulseñala que está intentando implementar el procesamiento de secuencia de control de un Teletipo Modelo 37 porque "eso es lo que nroffgenera". El sustituto GNU del nroffprograma Unix original, escrito mucho después de que los terminales adquirieran características sofisticadas como colores, negrita y cursiva, es capaz de generarECMA-48secuencias de control para colores, negrita y cursiva. En realidad lo haceen el caso normal.

nroff, y su reemplazo GNU, se utilizan para formatear páginas de manual para mostrarlas en su terminal. Lamentablemente, e irónicamente, aproximadamente 10 años después de que se escribiera, la gente procedió a obstaculizar la herramienta GNU para que generara las antiguas secuencias del Teletipo Modelo 37 de 1968 en lugar de las "nuevas" secuencias de control ECMA-48 de 1976 (¡sic!). Hicieron maninvoke groffcon opciones que modificaron su comportamiento predeterminado y agregaron archivos indocumentados que forzaron una salida ditroff adicional.

Cada vez que lee una página del manual en su terminal, se ejecuta el sistema del manual groff, que convierte diligentemente el texto fuente del manual en un flujo de caracteres de salida con estas antiguas secuencias de control Teletype Model 37, que se lessestán moreconvirtiendo en las secuencias de control de su terminal.

Otras lecturas

Respuesta2

Ctrl-Hes retroceso, mueve el cursor un paso hacia la izquierda. Enviar un guión bajo, un retroceso y algún otro carácter era la forma de subrayar algo en una terminal impresa ("papel") en los viejos tiempos. Esto se usó para resaltar el día actual en la salida de cal.

Mi calprograma, cuando se ejecuta, konsoleno genera esta secuencia. Si ejecuto script -c caly examino el typescriptarchivo resultante, puedo ver que el programa cal usa la secuencia de escape <esc>[7mpara cambiar al video en modo inverso.

información relacionada