Đối với những người có một chương trình liên tục viết lên thiết bị xuất chuẩn, tất cả những gì bạn cần làm là chuyển nó thành grep với tùy chọn 'một trận đấu'. Khi grep tìm thấy chuỗi phù hợp, nó sẽ thoát, nó sẽ đóng thiết bị xuất chuẩn trên tiến trình đang được dẫn đến grep. Sự kiện này tự nhiên sẽ khiến chương trình thoát ra một cách duyên dáng miễn là quá trình viết lại .
Điều gì sẽ xảy ra là quá trình sẽ nhận được SIGPIPE khi nó cố gắng ghi vào thiết bị xuất chuẩn sau khi grep đã thoát. Dưới đây là một ví dụ với ping, nếu không sẽ chạy vô thời hạn:
$ ping superuser.com | grep -m 1 "icmp_seq"
Lệnh này sẽ khớp với 'pong' thành công đầu tiên, và sau đó thoát ra trong lần tiếp theo ping
cố gắng viết vào thiết bị xuất chuẩn.
Tuy nhiên,
Không phải lúc nào cũng đảm bảo rằng quy trình sẽ ghi vào thiết bị xuất chuẩn một lần nữa và do đó có thể không khiến SIGPIPE được nâng lên (ví dụ: điều này có thể xảy ra khi nối đuôi tệp nhật ký). Giải pháp tốt nhất tôi đã quản lý để đưa ra cho kịch bản này liên quan đến việc ghi vào một tệp; hãy bình luận nếu bạn nghĩ rằng bạn có thể cải thiện:
$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }
Phá vỡ điều này:
tail -f log_file & echo $! > pid
- đuôi một tệp, đính kèm tiến trình vào nền và lưu PID ( $!
) vào tệp. Thay vào đó, tôi đã thử xuất PID thành một biến, nhưng có vẻ như có một điều kiện chạy đua giữa đây và khi PID được sử dụng lại.
{ ... ;}
- nhóm các lệnh này lại với nhau để chúng ta có thể dẫn đầu ra thành grep trong khi vẫn giữ bối cảnh hiện tại (giúp khi lưu và sử dụng lại các biến, nhưng không thể làm cho phần đó hoạt động)
|
- ống bên trái stdout sang phải stdin bên phải
grep -m1 "find_me"
- tìm chuỗi mục tiêu
&& kill -9 $(cat pid)
- lực lượng giết (SIGKILL) tail
quá trình sau khi grep
thoát khi tìm thấy chuỗi phù hợp
&& rm pid
- xóa tệp chúng tôi đã tạo
tail -f
là một đầu ra chương trình cũng như một tập tin ... Tôi có sai không?