Прервать порожденную программу, когда она печатает определенное предупреждение

Мой 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 еще лучше.

Другие вопросы по тегам