GNU/Linux >> Belajar Linux >  >> Linux

Membuat Tail -f Keluar Pada Pipa Rusak?

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.

Terkait:Bagaimana cara menggunakan kode status keluar ??

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).


Linux
  1. Bagaimana cara keluar jika perintah gagal?

  2. Bagaimana cara membuat file jarang?

  3. Pipa string ke Tanggal GNU untuk konversi - bagaimana cara membuatnya dibaca dari stdin?

  1. Memipipkan `find` ke 'tail`

  2. Makefile untuk tidak melakukan apa-apa

  3. Dari VMware dan Fedora 29 ssh ke mesin jarak jauh menyebabkan pipa Rusak

  1. Membaca Terus Menerus Dari Pipa Bernama (cat Atau Ekor -f)?

  2. Bagaimana Cara Membuat Pipa Dua Arah Antara Dua Program?

  3. Grep Dan Ekor -f?