Для тих, хто має програму, яка постійно пише в stdout, все, що вам потрібно зробити, - це передати її для вибору з опцією "єдиний матч". Як тільки grep знайде відповідний рядок, він вийде, що закриває stdout в процесі, який переносять на grep. Ця подія повинна, природно, спричинити виграшну програму, поки процес знову пише .
Що станеться, процес отримає SIGPIPE, коли він намагається записати у закритий stdout після виходу grep. Ось приклад з ping, який інакше працюватиме нескінченно:
$ ping superuser.com | grep -m 1 "icmp_seq"
Ця команда буде відповідати першому успішному 'pong', а потім вийти наступного разу, коли 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, зберігаючи поточний контекст (допомагає при збереженні та повторному використанні змінних, але не змогли цю частину працювати)
|
- труба лівої сторони вправо на праву сторону стдін
grep -m1 "find_me"
- знайти цільовий рядок
&& kill -9 $(cat pid)
- примусово знищити (SIGKILL) tail
процес після grep
виходу після того, як він знайде відповідний рядок
&& rm pid
- видаліть створений нами файл
tail -f
вивести програму так само добре, як і файл ... Я помиляюся?