Курсор исчезает при запуске `top -n1 | head`

11

При беге

top -n1 | head

курсор терминала исчезает. Бег top -n1возвращает это.

Протестировано в gnome-terminalи tilixв Ubuntu 16.04 и CentOS 7.5.


Запуск top -n1 | tailне имеет этой проблемы, так что я думаю, что-то в конце topвывода позволяет появиться курсору, который не выполняется при печати headтолько.

Что вызывает это и как я могу вернуть курсор более элегантно?

pLumo
источник
1
Я также могу вернуть его с бегом tput cnorm. ( через )
pLumo

Ответы:

5

Я не смог воссоздать это поведение везде, но оно появляется в Ubuntu 18.04


Поучительно изучить шестнадцатеричные дампы верхнего вывода:

$ 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
$ 

В частности, начальные последовательности 0x1b5b3f- это escape-последовательности ANSI , которые по сути являются метаданными для управления такими вещами, как положение курсора и цвет текста.

В частности, ближе к началу первой строки верхнего вывода есть ESC [?25l, а к концу последней строки есть ESC [?25h. Согласно странице википедии, это соответствующие коды, чтобы скрыть и показать курсор.

Путем передачи top -n1вывода headв терминал терминал получит команду скрытия курсора в начале, но не команду show-cursor в конце, и, следовательно, курсор останется невидимым, пока какое-либо другое действие не включит его снова.

@MrShunz предложение использовать -bопцию topправильно. Эта опция отключает все escape-последовательности ANSI в выводе top, вместо этого просто выводит простой печатный текст ASCII. Никакие курсоры не будут повреждены во время выполнения topс -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.
$ 
Цифровая травма
источник
Отличный ответ, спасибо. Поведение можно воспроизвести, printf \\033[?25lчтобы скрыть и printf \\033[?25hснова открыть курсор. Другие escape-последовательности [Hи [2Jочистка терминала (сравните clear | xxd)
pLumo
17

IMHO, лучший способ - topиспользовать «пакетный» режим ( -bфлаг), который предназначен для использования с неинтерактивными сценариями использования, такими как передача в другую программу или в файл.

Итак, это

top -n1 -b | head

не оставит оболочку без курсора.

Что касается того, почему курсор исчезает ...

Поскольку topэто интерактивная программа, она «портит» терминал, чтобы захватить ввод, прокрутить содержимое и т. Д., И скрывает курсор.

При завершении он должен восстановить курсор и состояние дисплея, которые он нашел перед вызовом, и делает это путем отправки одного или нескольких управляющих кодов на сам терминал.

При передаче команды через headэтот код управления не будет проходить ( headпо умолчанию печатаются только первые 10 строк, а выходные данные обоих topкодов и кодов управления для восстановления состояния терминала всегда> 10 строк).

Фактически, если вы дадите headдостаточно строк для печати, появится курсор!

Например,

top -n1 | head -n 100

оставляет курсор в моей системе.

Мистер Шунц
источник
Большое спасибо за ваш ответ. Использование -bэто путь для меня.
pLumo