Я ищу способ программно наблюдать за выводом команды, пока определенная строка не наблюдается, а затем выйти. Это очень похоже на этот вопрос, но вместо хвоста файла я хочу «хвостить» команду.
Что-то типа:
смотреть -n1 my_cmd | grep -m 1 "Строка, которую я ищу"
(Но это не работает для меня.)
ОБНОВЛЕНИЕ: Мне нужно уточнить, что my_cmd не выводит текст непрерывно, но его нужно повторно вызывать до тех пор, пока не будет найдена строка (вот почему я подумал о команде 'watch'). В этом отношении my_cmd похож на многие другие команды unix, такие как: ps, ls, lsof, last и т. Д.
tail -f
вывода программы так же, как файл ... Я ошибаюсь?Ответы:
Используйте цикл:
Вместо этого
:
вы можете использоватьsleep 1
(или 0,2) для облегчения работы процессора.Цикл выполняется до тех пор, пока grep не найдет строку в выводе команды.
-m 1
означает «достаточно одного совпадения», т.е. grep прекращает поиск после того, как находит первое совпадение.Вы также можете использовать
grep -q
метод, который также завершает работу после нахождения первого совпадения, но без печати совпадающей строки.источник
grep -q
что является еще одним вариантом. grep выходит после нахождения строки.!
отменяет код выхода командного конвейераgrep -m 1
выходит, когда строка найденаwatch -e
возвращает, если произошла какая-либо ошибкаНо это может быть улучшено, чтобы фактически отобразить эту согласованную линию, которая пока отброшена.
источник
watch
команда (CentOS) не имеет-e
флага (который не должен иметь значения). Что еще более важно, однако, когда строка найдена, watch продолжает работать и не выходит. Кажется, что когдаgrep -m
выходит, он только убиваетmy_cmd
, но не убиваетwatch
.tee
для этого, но это вводит в заблуждение новую строку, я не знаю, как обойти прямо сейчас:watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
watch
покорно перестает смотреть, когда строка найдена, но на самом деле она не завершается, пока вы не нажмете клавишу. Так близко.Для тех, у кого есть программа, которая постоянно записывает в stdout, все, что вам нужно сделать, это передать ее в grep с опцией 'single match'. Как только grep найдет соответствующую строку, он выйдет, что закроет стандартный вывод процесса, который передается в grep. Это событие должно естественным образом вызывать корректное завершение программы до тех пор, пока процесс не запишется снова .
Что произойдет, так это то, что процесс получит SIGPIPE, когда попытается записать в закрытый стандартный вывод после выхода grep. Вот пример с ping, который в противном случае работал бы бесконечно:
Эта команда будет соответствовать первому успешному pong, а затем завершится при следующей
ping
попытке записи в stdout.Тем не мение,
Не всегда гарантируется, что процесс снова запишет в stdout и, следовательно, может не вызывать SIGPIPE для поднятия (например, это может произойти при подключении файла журнала). Лучшее решение, которое мне удалось найти для этого сценария, включает запись в файл; пожалуйста, прокомментируйте, если вы думаете, что можете улучшить:
Разбивая это:
tail -f log_file & echo $! > pid
- привязывает файл, присоединяет процесс к фону и сохраняет PID ($!
) в файл. Вместо этого я попытался экспортировать PID в переменную, но, похоже, между этим моментом и тем, когда PID снова используется, возникает условие гонки.{ ... ;}
- сгруппировать эти команды вместе, чтобы мы могли направить вывод в grep, сохраняя текущий контекст (помогает при сохранении и повторном использовании переменных, но не смог заставить эту часть работать)|
- труба с левой стороны к правой сторонеgrep -m1 "find_me"
- найти целевую строку&& kill -9 $(cat pid)
- принудительно уничтожить (SIGKILL)tail
процесс послеgrep
выхода, когда он найдет соответствующую строку&& rm pid
- удалите файл, который мы создалиисточник
Если
tail
не поддерживает+1f
синтаксис, попробуйтеtail -f -n +1
. (Он-n +1
говорит, что должен начинаться с начала;tail -f
по умолчанию начинается с последних 10 строк вывода.)источник
Добавить результат ваших программных вызовов в файл. Тогда
tail -f
этот файл. Таким образом, это должно работать ... Я надеюсь.Когда вы возобновите вызов этой программы, вам придется стереть файл или добавить к нему немного тарабарщины, чтобы он не совпадал с тем, что вы искали.
источник