Kursor znika po uruchomieniu `top -n1 | głowa`

11

Podczas biegania

top -n1 | head

kursor terminala znika. Bieganie top -n1to przywraca.

Testowany w gnome-terminali tilixw Ubuntu 16.04 i CentOS 7.5.


Uruchomienie top -n1 | tailnie ma tego problemu, więc myślę, że coś na końcu topwyjścia pozwala na ponowne pojawienie się kursora, który nie jest wykonywany podczas drukowania headjedynego.

Co to powoduje i jak mogę bardziej elegancko przywrócić kursor?

pLumo
źródło
1
Mogę też odzyskać to po uruchomieniu tput cnorm. ( via )
pLumo,

Odpowiedzi:

5

Nie byłem w stanie odtworzyć tego zachowania wszędzie, ale pojawia się ono na Ubuntu 18.04


Pouczające jest sprawdzenie zrzutów szesnastkowych najwyższego wyjścia:

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

W szczególności początkowe sekwencje 0x1b5b3fsekwencjami ucieczkowymi ANSI , które skutecznie są metadanymi do kontrolowania takich pozycji, jak pozycja kursora i kolor tekstu.

W szczególności, na początku pierwszego wiersza najwyższego wyniku, jest ESC [?25l, a pod koniec ostatniego wiersza jest ESC [?25h. Zgodnie ze stroną wikipedii są to odpowiednie kody do ukrywania i pokazywania kursora.

Przesyłając dane top -n1wyjściowe do head, terminal otrzyma polecenie ukryj kursor na początku, ale nie polecenie pokaż kursor na końcu, a zatem kursor pozostanie niewidoczny, dopóki inne czynności nie włączy go ponownie.

Sugestia @MrShunz, aby użyć tej -bopcji, topjest odpowiednia. Ta opcja wyłącza wszystkie sekwencje specjalne ANSI w wynikach top, zamiast tego wyświetla zwykły tekst do wydruku ASCII. Brak kursory zostaną skrzywdzone podczas wykonywania topz -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.
$ 
Cyfrowa trauma
źródło
Świetna odpowiedź, dzięki. Zachowanie można odtworzyć w printf \\033[?25lcelu ukrycia i printf \\033[?25hponownego wyświetlenia kursora. Inne sekwencje specjalne [Hi [2Jwyczyść terminal (porównaj clear | xxd)
pLumo,
17

Najlepszym sposobem IMHO jest topużycie trybu „wsadowego” ( -bflaga), który ma być używany z nieinteraktywnymi przypadkami użycia, takimi jak przesyłanie potoków do innego programu lub pliku.

Więc to

top -n1 -b | head

nie opuści powłoki bez kursora.

Jeśli chodzi o to, dlaczego kursor znika ...

Ponieważ topjest to program interaktywny, „miesza się” z terminalem w celu przechwytywania danych wejściowych, przewijania zawartości itp. I ukrywa kursor.

Po zakończeniu musi przywrócić kursor i stan wyświetlania, który znalazł przed wywołaniem, i robi to, wysyłając jeden lub więcej kodów sterujących do samego terminala.

Po przesłaniu polecenia headten kod sterujący nie przejdzie ( headdomyślnie wypisuje tylko pierwsze 10 wierszy, a dane wyjściowe obu topkodów sterujących i przywracających stan terminala są zawsze> 10 wierszy).

W rzeczywistości, jeśli podasz headwystarczającą liczbę wierszy do wydrukowania, pojawi się kursor!

Na przykład,

top -n1 | head -n 100

pozostawia kursor w moim systemie.

Pan Shunz
źródło
Wielkie dzięki za odpowiedź. Korzystanie -bjest dla mnie sposobem.
pLumo,