Saya ingin menonton file sampai sedikit teks muncul
Saya menemukan jawaban ini:`tail -f` hingga teks terlihat
tapi pas saya coba di ubuntu gak keluar :
$ echo one > test.txt
$ echo two >> test.txt
$ echo three >> test.txt
$ echo four >> test.txt
$ cat test.txt | sed '/w/ q'
one
two
$
bekerja seperti yang diharapkan. namun ketika saya mencoba untuk mengekor file tersebut
$ tail -f test.txt | sed '/w/ q'
one
two
itu tidak pernah keluar. ekor tidak berhenti meskipun pipanya putus.
Ada yang tau cara bikin tail
keluar saat sed
keluar?
Jawaban yang Diterima:
Ini sama seperti di:
- Bagaimana cara keluar lebih awal pada penutupan pipa?
- Grep lambat untuk keluar setelah menemukan kecocokan?
- membatasi mencari keluaran DAN menghindari sinyal 13
Dalam:
cmd1 | cmd2
Shell Anda kebetulan menunggu sampai cmd1
berakhir bahkan setelah cmd2
sudah dihentikan. Itu bukan kasus semua cangkang. Beberapa seperti cangkang Bourne atau Korn misalnya tidak.
Ketika cmd2
mati, pipa di cmd1
stdout menjadi rusak , tapi itu tidak menghentikan cmd1
secara instan.
cmd1
akan berhenti saat berikutnya mencoba menulis ke pipa itu. Kemudian akan menerima SIGPIPE yang tindakan defaultnya adalah menghentikan proses.
Dengan cmd1
==tail -f file
dan cmd2
==sed /w/q
, tail -f
akan membaca 10 baris terakhir file dan menulisnya ke stdout (pipa), biasanya dalam satu potongan kecuali jika barisnya sangat besar dan duduk di sana menunggu lebih banyak teks ditambahkan ke file
.
sed
, yang berjalan secara bersamaan, akan menunggu input pada stdinnya, membacanya, memprosesnya baris demi baris dan berhenti jika ada baris yang berisi w
.
Segera (atau mungkin dengan penundaan satu baris dengan beberapa sed
implementasi) ketika menemukan baris itu, ia keluar, tetapi pada saat itu, tail
telah menulis ke pipa semua yang harus MENULIS, jadi itu tidak akan menerima SIGPIPE kecuali beberapa teks tambahan ditambahkan nanti ke file (di mana itu akan melakukan write()
yang fatal ).
Jika Anda ingin cmd1
untuk mengakhiri segera setelah cmd2
berakhir, Anda perlu sesuatu untuk mematikannya sekali cmd2
berakhir. Suka dengan:
sh -c 'echo "$$"; exec tail -f test.txt' | {
IFS= read pid
sed /w/q
kill -s PIPE "$pid"
}
Atau dengan bash
:
{ sed /w/q; kill -s PIPE "$!"; } < <(exec tail -f text.txt)
Edit 2020
Seperti yang dicatat oleh @user414777, sejak versi 8.28, implementasi GNU tail
, dalam mode ikuti, sekarang tidak hanya melakukan polling untuk data baru dalam file yang dipantau, tetapi juga memeriksa apakah stdout-nya menjadi pipa rusak dan langsung keluar (atau dalam satu detik jika notify tidak digunakan), membuat pekerjaan di atas tidak diperlukan.
Namun perhatikan bahwa hanya GNU tail
melakukan pemrosesan semacam ini, bukan implementasi tail
lainnya (AFAIK), dan bukan utilitas lain (bahkan implementasi GNU).
Jadi, sementara:
tail -f file | head -n1
Akan keluar setelah satu baris,
tail -f file | tr '[:lower:]' '[:upper:]' | head -n1
misalnya tidak harus sebagai tr
tidak akan memantau apakah stdoutnya menjadi pipa yang rusak, dan hanya akan mati jika menulis sesuatu di sana setelah pipa rusak seperti biasa (dan hanya pada saat itulah GNU tail -f
akan keluar).