Bagaimana cara mengubah isi baris pada terminal dan bukannya menulis yang baru?


24

Jadi, ketika wgetmendapatkan halaman web, itu menunjukkan Anda bilah status yang menunjukkan berapa banyak file yang diunduh. Ini terlihat seperti ini:

25%[=============>______________________________________] 25,000 100.0K/s (garis bawah adalah spasi; Saya hanya tidak tahu bagaimana mendapatkan lebih dari satu spasi berturut-turut di sana)

Namun, alih-alih menulis baris lain ke stdout dan menambahkan bilah progres, ini memperbaruinya, seperti ini:

50%[===========================>________________________] 50,000 100.0K/s

Dan wgetbukan satu-satunya contohnya. Misalnya, ketika Anda menyalurkan sesuatu ke dalam lessdan kemudian keluar, prompt asli Anda masih ada, bersama dengan hasil dari perintah apa pun yang Anda jalankan sebelumnya. Sepertinya Anda tidak pernah pergi.

Jadi, pertanyaan saya adalah, apa sebutannya ini, bagaimana saya mengimplementasikannya, apakah hanya berfungsi untuk satu baris pada satu waktu, dan dapatkah saya menggunakan ini dalam C?


5
Saya merekomendasikan membaca BashFAQ 44 . Anda mungkin menemukan itu menarik.
jw013

Jawaban:


32

Pertama-tama pertanyaan Anda tidak ada hubungannya dengan bash tetapi dengan terminal. Terminal merespons untuk menampilkan teks program dan bash sendiri tidak memiliki kendali atas program begitu diluncurkan.

Terminal menawarkan urutan kontrol untuk mengontrol warna, font, posisi kursor, dan lainnya. Untuk daftar urutan terminal standar, lihat di http://www.termsys.demon.co.uk/vtansi.htm Anda dapat misalnya

  • posisikan kursor di awal baris
  • hapus baris setelahnya
  • tulis baris baru

untuk membuat bilah kemajuan.

Urutan pelarian terminal yang lebih maju biasanya tergantung terminal, mis. Bekerja hanya dengan Eterm atau xterm. ncurses - adalah pustaka pemrograman yang membuat program interaktif dengan terminal sehingga Anda tidak perlu menggunakan urutan pelarian.

Cara menimpa baris yang ada dengan urutan terminal

echo long text
sleep 1
printf "\033[1A"  # move cursor one line up
printf "\033[K"   # delete till end of line
echo foo

Cara menimpa saluran yang ada tanpa urutan terminal

Salah satu solusi sederhana adalah tidak menulis baris baru di akhir tetapi menulis carriage return, yang pada dasarnya mengatur ulang kursor ke awal baris, misalnya:

echo -n first 
sleep 1 
echo -ne "\rsecond"
echo

Pengembalian \ratau carriage akan meletakkan kursor di awal baris dan memungkinkan Anda untuk menimpa konten baris.

Beralih di antara buffer seperti lessatauvi

Perilaku lessjuga karena fitur terminal yang lebih canggih, layar alternatif:

Dalam mode VT102, ada urutan melarikan diri untuk mengaktifkan dan menonaktifkan buffer layar alternatif, yang ukurannya sama dengan area tampilan jendela. Saat diaktifkan, layar saat ini disimpan dan diganti dengan layar alternatif. Menyimpan garis yang digulir dari bagian atas jendela dinonaktifkan hingga layar normal dipulihkan. Entri term cap (5) untuk xterm memungkinkan editor visual vi (1) untuk beralih ke layar alternatif untuk mengedit dan mengembalikan layar saat keluar. Entri menu popup memudahkan beralih antara layar normal dan layar alternatif untuk memotong dan menempel.

http://rosettacode.org/wiki/Terminal_control/Preserve_screen mencantumkan beberapa contoh cara melakukannya sendiri, baik melalui tput atau melalui beberapa urutan pelarian.


15

Alih-alih menggunakan echoyang secara otomatis menambahkan baris baru ke string, gunakan printf "%s\r" whatever- carriage return mengirim kursor ke awal baris saat ini. contoh:

seq 1 15 | while read num; do printf "%2d\r" $num; sleep 1; done; echo ""

tergantung pada kursor terminal Anda, mungkin lebih menyenangkan untuk melakukannyaprintf "\r%2d " $num
glenn jackman
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.