Прервать порожденную программу, когда она печатает определенное предупреждение
Мой Bash 4 скрипт вызывает стороннюю программу P
(тот, который я не могу перекомпилировать), который выводит предупреждения на STDOUT. Когда он печатает yikes
также входит в бесконечный цикл. Поэтому, когда я обнаруживаю yikes
как я могу сразу остановиться P
и вернуть контроль над моим сценарием? (И разреши P
закончу нормально иначе.)
Возможно полезные фрагменты:
(echo $BASHPID > /tmp/subpid; ./P | tee /tmp/Pout ) &
tail -f /tmp/Pout | grep -m1 yikes && kill -9 $(cat /tmp/subpid)
wait
2 ответа
Использование expect
:
P | { expect -c 'expect -timeout -1 yikes' && killall P ; }
Это использование не может быть оптимальным, все же expect
это правильный инструмент для работы.
Если P
печатает больше после yikes
тогда он заметит сломанную трубу, поэтому killall
не требуется:
P | expect -c 'expect -timeout -1 yikes'
coproc ./P
grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID
Демо-версия:
coproc { sleep 1; echo yikes; sleep 2; }; grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID
coproc { sleep 1; echo zzzzz; sleep 2; }; grep -q -m1 yikes <&${COPROC[0]} && [[ $COPROC_PID ]] && kill -9 $COPROC_PID
Найдено по https://stackoverflow.com/a/26779617/2097284.
Однако https://unix.stackexchange.com/questions/86270/how-do-you-use-the-command-coproc-in-bash объясняет, почему именованные каналы лучше (хотя тупик здесь невозможен), и Зачем expect
еще лучше.