Cursor desaparece ao executar 'top -n1 | cabeça'

11

Ao executar

top -n1 | head

o cursor do terminal desaparece. A execução de top -n1 traz de volta.

Testado em gnome-terminal e tilix no Ubuntu 16.04 e no CentOS 7.5.

A execução de top -n1 | tail não tem esse problema, então, acho que algo no final de top output deixou o cursor reaparecer, o que não é executado ao imprimir apenas o head .

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

    
por RoVo 18.09.2018 / 12:42

2 respostas

5

Eu não consegui recriar esse comportamento em todos os lugares, mas ele aparece no Ubuntu 18.04

É instrutivo examinar os dumps hexadecimais da saída principal:

$ 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 que iniciam 0x1b5b3f sã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, em relação ao início da primeira linha da saída principal, há ESC [?25l e, 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.

Por canalizar a saída top -n1 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é alguma outra ação liga-o novamente.

Sugestão @MrShunz para usar a opção -b para top está correta. Essa opção desativa todas as seqüências de escape ANSI na saída do topo, em vez disso, apenas exibe texto simples imprimível ASCII. Nenhum cursor será danificado durante a execução de top com -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.
$ 
    
por 18.09.2018 / 22:56
18

Melhor maneira IMHO é fazer top usar o modo "batch" ( -b flag) que se destina a ser usado com casos de uso não interativos, como tubulação para outro programa ou para um arquivo.

Então, isso

top -n1 -b | head

não sairá da shell sem um cursor.

Quanto ao porque o cursor desaparece ...

Como top é um programa interativo, ele "mexe" com o terminal para capturar entrada, conteúdo de rolagem, etc, e oculta o cursor.

Ao terminá-lo, ele deve restaurar o cursor e o status de exibição antes de ser chamado, e o faz enviando um ou mais códigos de controle para o próprio terminal.

Por canalizar o comando através de head , esse código de controle não passará ( head imprime apenas as 10 primeiras linhas por padrão e a saída de top e os códigos de controle para restaurar o estado do terminal é sempre > 10 linhas).

Na verdade, se você der a head linhas suficientes para imprimir, o cursor aparece!

Por exemplo,

top -n1 | head -n 100

deixa um cursor no meu sistema.

    
por 18.09.2018 / 12:52