El cursor desaparece cuando se ejecuta `top -n1 | cabeza`

11

Cuando se ejecuta

top -n1 | head

el cursor del terminal desaparece. Correr lo top -n1trae de vuelta.

Probado en gnome-terminaly tilixen Ubuntu 16.04 y CentOS 7.5.


La ejecución top -n1 | tailno tiene este problema, así que creo que algo al final de la topsalida permite que vuelva a aparecer el cursor que no se ejecuta al imprimir el headúnico.

¿Qué causa esto y cómo puedo volver el cursor con más elegancia?

pLumo
fuente
1
También puedo recuperarlo corriendo tput cnorm. ( vía )
pLumo

Respuestas:

5

No pude recrear este comportamiento en todas partes, pero aparece en Ubuntu 18.04


Es instructivo examinar los volcados hexadecimales de la salida superior:

$ top -n1 | head -n1 | xxd
00000000: 1b5b 3f31 681b 3d1b 5b3f 3235 6c1b 5b48  .[?1h.=.[?25l.[H
00000010: 1b5b 324a 1b28 421b 5b6d 746f 7020 2d20  .[2J.(B.[mtop - 
00000020: 3133 3a34 333a 3034 2075 7020 3120 6d69  13:43:04 up 1 mi
00000030: 6e2c 2020 3120 7573 6572 2c20 206c 6f61  n,  1 user,  loa
00000040: 6420 6176 6572 6167 653a 2030 2e38 312c  d average: 0.81,
00000050: 2030 2e35 342c 2030 2e32 321b 2842 1b5b   0.54, 0.22.(B.[
00000060: 6d1b 5b33 393b 3439 6d1b 2842 1b5b 6d1b  m.[39;49m.(B.[m.
00000070: 5b33 393b 3439 6d1b 5b4b 0a              [39;49m.[K.
$ top -n1 | tail -n1 | xxd
00000000: 1b5b 3f31 326c 1b5b 3f32 3568 1b5b 4b    .[?12l.[?25h.[K
$ 

En particular, las secuencias que comienzan 0x1b5b3fson secuencias de escape ANSI , que efectivamente son metadatos para controlar cosas como la posición del cursor y el color del texto.

En particular, hacia el comienzo de la primera línea de salida superior, hay ESC [?25l, y hacia el final de la última línea es ESC [?25h. Según la página de wikipedia, estos son los códigos respectivos para ocultar y mostrar el cursor.

Al canalizar la top -n1salida a head, el terminal recibirá el comando hide-cursor al comienzo, pero no el comando show-cursor al final, y por lo tanto el cursor permanecerá invisible hasta que alguna otra acción lo encienda nuevamente.

La sugerencia de @MrShunz para usar la -bopción topes correcta. Esta opción deshabilita todas las secuencias de escape ANSI en la salida de la parte superior, en su lugar solo genera un texto imprimible ASCII simple. No se dañarán los cursores durante la ejecución de topcon -b:

$ top -b -n1 | head -n1 | xxd
00000000: 746f 7020 2d20 3133 3a35 393a 3236 2075  top - 13:59:26 u
00000010: 7020 3138 206d 696e 2c20 2031 2075 7365  p 18 min,  1 use
00000020: 722c 2020 6c6f 6164 2061 7665 7261 6765  r,  load average
00000030: 3a20 302e 3134 2c20 302e 3036 2c20 302e  : 0.14, 0.06, 0.
00000040: 3037 0a                                  07.
$ 
Trauma digital
fuente
Gran respuesta, gracias. El comportamiento puede reproducirse printf \\033[?25lpara ocultar y printf \\033[?25hvolver a mostrar el cursor. Las otras secuencias de escape [Hy [2Jborrar el terminal (comparar clear | xxd)
pLumo
17

La mejor manera en mi humilde opinión es hacer topuso del modo "por lotes" ( -bbandera) que está destinado a ser utilizado con casos de uso no interactivos, como la canalización a otro programa o un archivo.

Así que esto

top -n1 -b | head

no dejará el shell sin un cursor.

En cuanto a por qué desaparece el cursor ...

Como topes un programa interactivo, se "mete" con el terminal para capturar entradas, desplazar contenido, etc., y oculta el cursor.

Al finalizar, debe restaurar el cursor y el estado de visualización que encontró antes de ser llamado, y lo hace enviando uno o más códigos de control al terminal.

Al pasar el comando head, este código de control no pasará ( headimprime solo las primeras 10 líneas de forma predeterminada, y la salida de ambos topy los códigos de control para restaurar el estado del terminal es siempre> 10 líneas).

De hecho, si le das headsuficientes líneas para imprimir, ¡aparece el cursor!

Por ejemplo,

top -n1 | head -n 100

deja un cursor en mi sistema.

Señor shunz
fuente
Muchas gracias por tu respuesta. Usar -bes el camino a seguir para mí.
pLumo