สำหรับผู้ที่มีโปรแกรมที่เขียนไปยัง stdout อย่างต่อเนื่องสิ่งที่คุณต้องทำคือไปที่ grep ด้วยตัวเลือก 'การจับคู่ครั้งเดียว' เมื่อ grep ค้นหาสตริงที่ตรงกันมันจะออกซึ่งจะปิด stdout ในกระบวนการที่กำลังถูกไพพ์ไปยัง grep เหตุการณ์นี้ควรจะเป็นธรรมชาติทำให้โปรแกรมอย่างสง่างามออกตราบใดที่กระบวนการเขียนอีกครั้ง
จะเกิดอะไรขึ้นคือกระบวนการจะได้รับ SIGPIPE เมื่อพยายามเขียนไปยัง stdout ปิดหลังจาก grep ได้ออก นี่คือตัวอย่างของการ ping ซึ่งจะรันแบบไม่มีกำหนด:
$ ping superuser.com | grep -m 1 "icmp_seq"
คำสั่งนี้จะตรงกับ 'พงษ์' ที่ประสบความสำเร็จครั้งแรกและจากนั้นออกในครั้งต่อไปping
พยายามเขียนถึง stdout
อย่างไรก็ตาม
ไม่รับประกันเสมอว่ากระบวนการจะเขียนไปยัง stdout อีกครั้งและอาจไม่ทำให้ SIGPIPE ถูกยกขึ้น (เช่นอาจเกิดขึ้นเมื่อทำการปรับแต่งล็อกไฟล์) ทางออกที่ดีที่สุดที่ฉันได้รับมาสำหรับสถานการณ์นี้เกี่ยวข้องกับการเขียนลงไฟล์ โปรดแสดงความคิดเห็นหากคุณคิดว่าคุณสามารถปรับปรุง:
$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }
ทำลายมันลง:
tail -f log_file & echo $! > pid
- ตัดไฟล์แนบกระบวนการเป็นพื้นหลังและบันทึก PID ( $!
) ไปยังไฟล์ ฉันลองส่งออก PID ไปยังตัวแปรแทน แต่ดูเหมือนว่ามีสภาพการแข่งขันระหว่างที่นี่และเมื่อใช้ PID อีกครั้ง
{ ... ;}
- จัดกลุ่มคำสั่งเหล่านี้เข้าด้วยกันเพื่อให้เราสามารถไพพ์เอาต์พุตเป็น grep ขณะที่รักษาบริบทปัจจุบัน (ช่วยเมื่อบันทึกและนำตัวแปรกลับมาใช้ใหม่ แต่ไม่สามารถทำงานส่วนนั้นได้)
|
- stdout ของท่อทางซ้ายไปยัง stdin ทางด้านขวา
grep -m1 "find_me"
- ค้นหาสตริงเป้าหมาย
&& kill -9 $(cat pid)
- บังคับให้ฆ่า (SIGKILL) tail
กระบวนการหลังจาก grep
ออกเมื่อพบสตริงที่ตรงกัน
&& rm pid
- ลบไฟล์ที่เราสร้าง
tail -f
ส่งออกโปรแกรมเช่นเดียวกับไฟล์ ... ฉันผิดหรือเปล่า?