Kursor menghilang ketika menjalankan `top -n1 | kepala`

11

Saat berlari

top -n1 | head

kursor terminal menghilang. Berlari top -n1membawanya kembali.

Diuji dalam gnome-terminaldan tilixdi Ubuntu 16.04 dan CentOS 7.5.


Berjalan top -n1 | tailtidak memiliki masalah ini, jadi saya pikir, sesuatu di akhir topoutput membiarkan kursor muncul kembali yang tidak dieksekusi saat mencetak headsatu - satunya.

Apa yang menyebabkan ini dan bagaimana saya bisa mendapatkan kursor lebih elegan?

pLumo
sumber
1
Saya juga bisa mendapatkannya kembali dengan berlari tput cnorm. ( via )
pLumo

Jawaban:

5

Saya tidak dapat membuat ulang perilaku ini di mana-mana, tetapi itu muncul di Ubuntu 18.04


Penting untuk memeriksa hex dumps dari output teratas:

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

Secara khusus, urutan mulai 0x1b5b3fadalah urutan melarikan diri ANSI , yang secara efektif adalah meta-data untuk mengontrol hal-hal seperti posisi kursor dan warna teks.

Secara khusus, menjelang awal baris pertama output atas, ada ESC [?25l, dan menjelang akhir baris terakhir adalah ESC [?25h. Sesuai halaman wikipedia, ini adalah kode terkait untuk menyembunyikan dan menampilkan kursor.

Dengan memipakan top -n1output ke head, terminal akan menerima perintah hide-cursor di awal, tetapi bukan perintah show-cursor di akhir, dan karenanya kursor akan tetap tidak terlihat sampai beberapa tindakan lain menyalakannya kembali.

@MrShunz saran untuk menggunakan -bopsi topini sudah tepat. Opsi ini menonaktifkan semua urutan pelarian ANSI di output atas, alih-alih hanya mengeluarkan teks ASCII yang dapat dicetak. Tidak ada kursor yang akan dirugikan selama eksekusi topdengan -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
sumber
Jawaban yang bagus, terima kasih. Perilaku dapat direproduksi dengan printf \\033[?25lmenyembunyikan dan printf \\033[?25hmengungkapkan kursor lagi. Urutan melarikan diri lainnya [Hdan [2Jmenghapus terminal (bandingkan clear | xxd)
pLumo
17

Cara terbaik IMHO adalah topmenggunakan mode "bets" ( -bbendera) yang dimaksudkan untuk digunakan dengan kasus penggunaan non-interaktif seperti pemipaan ke program lain atau ke file.

Jadi ini

top -n1 -b | head

tidak akan meninggalkan shell tanpa kursor.

Adapun mengapa kursor menghilang ...

Karena topmerupakan program interaktif, ia "mengacaukan" terminal untuk mengambil input, menggulir konten, dll, dan menyembunyikan kursor.

Ketika mengakhiri itu harus mengembalikan kursor dan status tampilan yang ditemukan sebelum dipanggil, dan melakukannya dengan mengirimkan satu atau lebih kode kontrol ke terminal itu sendiri.

Dengan memipakan perintah melalui head, kode kontrol ini tidak akan melewati ( headmencetak hanya 10 baris pertama secara default, dan output dari keduanya topdan kode kontrol untuk mengembalikan keadaan terminal selalu> 10 baris).

Bahkan, jika Anda memberikan headgaris yang cukup untuk dicetak, kursor akan muncul!

Sebagai contoh,

top -n1 | head -n 100

meninggalkan kursor di sistem saya.

Tuan Shunz
sumber
Terima kasih banyak atas jawaban Anda. Menggunakan -badalah cara untuk saya.
pLumo