Допустим, я запускаю процесс, и он выполняет очень длительную процедуру, выводя свой прогресс на стандартный вывод. Есть ли способ завершить процесс автоматически после
- х строк вывода
или - определенное ключевое слово было найдено в выводе?
В настоящее время я уже перенаправив вывод команды x
на egrep 'search pattern
и хотите прекратить x
после того, как egrep
показывает определенную линию.
Я представляю, есть ли какой-нибудь способ написания сценария:
run command `y` after `x` lines of output are seen on previous apps piped `sdout`
Я мог бы справиться с этим довольно легко, например:
mylongrunningtool | egrep '(term1|term2)' | runafterxlines --lines=8 --command='killall -9 mylongrunnigtool`
Любой берущий?
command-line
unix
Махмуд Аль-Кудси
источник
источник
Ответы:
Попробуйте
head
команду:head
позволяет указать количество строк. Обратитесь к странице руководства для получения дополнительной информации.loop.py
:loop.py
должен работать бесконечно, но если я передам его выводhead
, я получу:Обратите внимание, что
Traceback ...
часть error ( ) на самом делеstderr
, как демонстрирует выполнение./loop.py 2> stderr.log | head
, поэтому вам не нужно беспокоиться о том, чтобы очистить вывод head.Наконец, для поиска:
Здесь, я перенаправлен
stderr
изloop.py
вне пути , даже если мы уверены , что не будет вмешиваться в тексте обрабатываетсяhead
иgrep
РЕДАКТИРОВАТЬ
TL; DR : Планировщик ЦП контролирует, насколько интенсивный процесс будет выполняться после
head
завершения вывода.После некоторого тестирования я обнаружил, что мое решение, хотя оно и снижает производительность
loop.py
, не настолько надежно, как это можно сделать. С этими модификациями к myloop.py
, конвейерный вывод в head дает:новый
loop.py
:и вывод:
Я скрыл некоторые результаты и оставил только соответствующие части. По сути, выходные данные показывают, что
head
стандартные потоки ввода / вывода (и, я полагаю, все процессы) буферизируются.Согласно этому ответу на SO , когда приемник (
head
) завершается, канал прерывается, и * только когда отправитель (loop.py
) пытается выполнить запись в теперь разорванный канал *, сигнал SIGPIPE будет отправляться на него.Поэтому, когда
head
появилась возможность напечатать свой вывод, все это обнаружилось сразу, но только после того, какloop.py
продолжилось еще 247 строк. (Это связано с планированием процессов.) Более того, после того, какhead
он напечатал свой вывод, но до его завершения, планировщик возобновил работуloop.py
, поэтому еще 250 строк (до 488) были записаны в канал, прежде чем канал был разорван.Для лучших результатов мы можем использовать небуферизованный ввод / вывод (в этом случае небуферизованный вывод
loop.py
). Вызывая интерпретатор python с-u
опцией, мы получаем:Конечно, это просто, если ваша программа написана на python, так как вам не нужно вносить изменения в код. Однако, если он находится в C, и у вас есть источник для него, вы можете использовать функцию
setvbuf()
в,stdio.h
чтобы установить вstdout
качестве небуферизованного:loop.c
:источник
head
не убьет процесс, верно? Моя проблема не связана с синтаксическим анализом, а связана со временем процессора. Я не хочу, чтобы этот длительный процесс продолжался.timelimit
сделает свое дело.stdbuf
для достижения желаемой буферизации для любой программы, которая может быть запущена из командной строки, не нужно редактировать исходный код.Я полагаю, что
grep
пример в принятом ответе не работает так, как ожидал OP (то есть процесс не будет убит после появления в строке «6»). Чтобы убить процесс после того, как он дает определенный вывод, можно использоватьВот как это работает:
>&-
закрываетstdout
, поэтому любая попытка записи приведет к ошибке.egrep '(term1|term2)'
отбрасывает все выходные данные, кроме строк, содержащих ключевое слово, в этом примере, «term1» или «term2».stdbuf -o0
отключает буферизацию вывода дляegrep
Как только одно из ключевых слов будет найдено в выходных данных
mylongrunningtool
,egrep
будет выполнено его передачаstdout
и завершится с ошибкой записи. В результатеSIGPIPE
будет отправлено сообщение,mylongrunningtool
которое убьет его по очереди.Юридическая информация:
Поскольку сигналы асинхронны,
mylongrunningtool
возможно, есть шанс выполнить некоторый код после оператора, к которому было добавлено ключевое словоstdout
, и практически невозможно гарантировать, сколько кода будет выполнено. В худшем случае, еслиmylongrunningtool
запросить драйвер устройства для операции, которая длится в течение часа (или навсегда), он будет работать еще один час (или навсегда), прежде чем его убьют.Кроме того,
SIGPIPE
может быть обработано, в отличие отSIGKILL
. Это означает, чтоmylongrunningtool
можно просто игнорировать сигнал и продолжать его работу. Обработка по умолчаниюSIGPIPE
, однако, должна быть прекращена.источник
Может быть, скрипт-обертка может быть полезен в этом случае. Идея состоит в том, чтобы запустить программу в фоновом режиме и направить ее вывод в файл.
Когда выходной файл удовлетворяет заданным требованиям (содержит некоторую строку или количество строк), закройте программу.
источник
$OUTPUT
и$SEARCH_STRING
на моем Mac.