Bagaimana membatasi jumlah baris yang dihasilkan oleh sebuah perintah dalam bash?

11

Saya mulai mengunduh file besar di latar belakang menggunakan

$ nohup wget http://example.tld/big.iso &

yang juga memberi saya nohup.outfile yang mencakup keluaran dari wget.

Sekarang, jika nanti saya ingin menonton proses pengunduhan, saya bisa menggunakan $ tail -f nohup.outtetapi itu mengisi jendela terminal saya lebih cepat dari yang saya harapkan. Yang ingin saya lihat adalah baris terakhir yang terus diperbarui (seperti saat menggunakan wgetsendiri).

Saya mencoba $ tail -n 1 -f nohup.outtetapi tampaknya hanya mempengaruhi awal tailin '.

Secara umum, jika dimungkinkan untuk membatasi (dalam hal ini ke 1) jumlah baris yang tersedia / terlihat oleh perintah akan menyelesaikan masalah ini. Semacam memiliki output dalam buffer Circular - pikirkan saja progress bar normal yang $ wget example.tld/big.isoakan dicetak.

Apakah ada solusi seperti itu?

Atau apakah saya salah memanjat pohon? (Artinya, apakah akan lebih mudah membatasi nohupoutput atau melakukan sesuatu yang lain?)

Jari Keinänen
sumber

Jawaban:

10

Jika Anda tidak ingin membatasi wilayah pengguliran (lihat jawaban saya yang lain), Anda juga dapat menggunakan carriage return untuk kembali ke awal baris sebelum mencetak baris berikutnya. Ada urutan keluar yang membersihkan sisa garis, yang diperlukan ketika garis saat ini lebih pendek dari garis sebelumnya.

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
el="$(tput el)"; # Clear to the end of the line
tail -n 1 -f nohup.out | while read -r line; do echo -n $'\r'"$el$line"; done;
janmoesen
sumber
6

Anda bisa menggunakannya di watchsini:

watch -n 0.5 -e "tail -n 1 nohup.out"

Sunting : Opsi -e(alias --exec) terlihat cocok di sini. Terutama jika Anda bertujuan berlari watchdengan interval yang sangat kecil, ini mengurangi overhead yang disebabkan oleh berjalan secara sh -cinternal watchdi setiap siklus.

rozcietrzewiacz
sumber
2
Perhatikan bahwa ini memunculkan tailproses baru setiap detik, yang mungkin atau mungkin bukan sesuatu yang Anda pedulikan. Juga, pastikan untuk menentukan interval sub-detik (mis. watch -n 0.1) Untuk mensimulasikan bagian "terus-menerus memperbarui". (Ini jelas meningkatkan jumlah proses dan mengajukan panggilan terbuka juga.) Akhirnya, jika Anda menggunakan OS X, Anda bisa dapatkan watchdari MacPorts, karena tidak tersedia secara default.
janmoesen
Ini sedikit pemecahan masalah, tetapi hebat seperti itu. Saya mengharapkan jawaban non-layar penuh, sehingga saya akan melihat keluaran sebelumnya - tetapi saya benar-benar dapat menggunakan watchjendela terminal baru. Saya juga menemukan bahwa menggunakan tail -n 2lebih bermanfaat daripada -n 1dengan wget, setidaknya dengan watchinterval 1 detik, karena jika tidak persentase terbaru mungkin tidak terlihat; ini bukan cacat dalam jawaban Anda, tapi saya sebutkan jika orang lain memutuskan untuk menonton woh tailed nohup output.
Jari Keinänen
@janmoesen Untuk skenario khusus ini, memiliki tailproses baru mungkin tidak berlebihan; tetapi sebagai jawaban umum ini bagus untuk diperhitungkan. Saya juga mencatat bahwa watch -n 0.1tidak berfungsi, tetapi watch -n 0,1berhasil - mungkin ada lokal yang diterapkan, meskipun saya belum melihat lokal diterapkan pada opsi perintah terminal sebelumnya. Sebagai catatan: brew install watchbekerja dengan sangat baik :-)
Jari Keinänen
Catatan tambahan: Apakah watchakan berfungsi 0,1atau 0.1tergantung pada pengaturan lokal Anda (menggunakan simbol desimal yang ditentukan untuk lokal Anda). Periksa LC_ALL=C watch -n 0.1 "date +%S.%N".
rozcietrzewiacz
3

Ada urutan kontrol Xterm tertentu yang dapat Anda gunakan untuk membatasi garis terminal Anda yang digulir. Cari "Set Scrolling Region". Tapi ini sedikit omong kosong. Pastikan untuk mereset terminal Anda setelahnya:

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
clear; echo -n $'\e[1;2r'; tail -f nohup.out | grep --line-buffered .
# The "grep" line is to ensure a single line; you can also use "awk 1" or "sed" etc.
janmoesen
sumber
<Masukkan catatan yang biasa tentang non-portabilitas di sini>
janmoesen
Ini adalah alternatif lain yang bagus, tetapi salah satu yang juga paling baik digunakan di jendela khusus karena tail -fmasih mengisi buffer dan juga karena terminal perlu diatur ulang setelahnya. Ini tidak sejajar seperti yang saya harapkan, tetapi sebaliknya mungkin itu yang saya cari.
Jari Keinänen
0

Jika Anda tidak ingin output menempati seluruh jendela terminal saat ini, Anda dapat menggunakan whileloop sederhana :

while true; do 
  XXX=$( tail -n1 my.log )
  echo -en " \r$XXX\r"
  sleep 0.5
done; echo
rozcietrzewiacz
sumber
1
Perhatikan bahwa untuk dapat menggulir output terminal sementara setiap output perintah-memproduksi berjalan, Anda perlu mengedit pengaturan emulator terminal Anda dan menonaktifkan scrollTtyOutput(atau serupa) pilihan.
rozcietrzewiacz