O cursor desaparece ao executar `top -n1 | cabeça`

11

Ao executar

top -n1 | head

o cursor do terminal desaparece. Correr top -n1traz de volta.

Testado em gnome-terminale tilixno Ubuntu 16.04 e CentOS 7.5.


A execução top -n1 | tailnão tem esse problema, então eu acho que algo no final da topsaída deixa o cursor reaparecer, o que não é executado ao imprimir o headúnico.

O que causa isso e como posso recuperar o cursor com mais elegância?

pLumo
fonte
1
Também posso recuperá-lo com a execução tput cnorm. ( via )
pLumo

Respostas:

5

Não consegui recriar esse comportamento em qualquer lugar, mas ele aparece no Ubuntu 18.04


É instrutivo examinar dumps hexadecimais da saída 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
$ 

Em particular, as sequências iniciadas 0x1b5b3fsão sequências de escape ANSI , que efetivamente são metadados para controlar coisas como a posição do cursor e a cor do texto.

Em particular, no início da primeira linha de saída superior, existe ESC [?25le no final da última linha é ESC [?25h. De acordo com a página da Wikipedia, estes são os respectivos códigos para ocultar e mostrar o cursor.

Ao canalizar a top -n1saída para head, o terminal receberá o comando hide-cursor no início, mas não o comando show-cursor no final e, portanto, o cursor permanecerá invisível até que alguma outra ação o ligue novamente.

A sugestão do @Shrzz de usar a -bopção topestá correta. Esta opção desativa todas as seqüências de escape ANSI na saída superior, apenas produzindo texto imprimível ASCII simples. Nenhum cursor será prejudicado durante a execução de topcom -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
fonte
Ótima resposta, obrigado. O comportamento pode ser reproduzido com printf \\033[?25lpara ocultar e printf \\033[?25hrevelar o cursor novamente. As outras sequências de escape [He [2Jlimpar o terminal (comparar clear | xxd)
pLumo
17

A melhor maneira do IMHO é topusar o modo "lote" ( -bsinalizador) que se destina a ser usado com casos de uso não interativos, como canalização para outro programa ou arquivo.

Então, é isso

top -n1 -b | head

não sairá do shell sem um cursor.

Quanto ao motivo pelo qual o cursor desaparece ...

Como topé um programa interativo, ele "mexe" com o terminal para pegar entradas, rolar conteúdo, etc., e oculta o cursor.

Ao finalizar, é necessário restaurar o cursor e o status de exibição encontrado antes de ser chamado, enviando um ou mais códigos de controle para o próprio terminal.

Ao canalizar o comando head, esse código de controle não será aprovado ( headimprime apenas as 10 primeiras linhas por padrão, e a saída de ambos tope dos códigos de controle para restaurar o estado do terminal é sempre> 10 linhas).

De fato, se você der headlinhas suficientes para imprimir, o cursor aparecerá!

Por exemplo,

top -n1 | head -n 100

deixa um cursor no meu sistema.

Shunz
fonte
Muito obrigado pela sua resposta. Usar -bé o caminho a percorrer para mim.
PLumo