Как в Linux ожидать строку от процесса с определенным таймаутом

Допустим вам необходимо дождаться от запущенного вами процесса определенной строки, означающей что все хорошо.

И после этого принудительно завершить процесс, но вернуть успешный код выхода. Чтобы ваш CI, например, оставался заленым.

Если же строки нет, то убить процесс если он сам не завершился и вернуть код неуспеха.

Вам повезло - я сейчас покажу, как это можно очень просто сделать.

И даже если вам именно этого сейчас не надо, вы заткнете за пояс пару BASH-трюков.

Первая строка это стандартная команда для запуска процесса с таймаутом.

Я добавил еще параметр -k который приведет к более жесткому завершению процесса если он не отреагировал на сигнал штатного завершения при наступлении таймаута.

Также используется ключ --preserve-status чтобы timeout вернул код результата контролируемого им процесса.

Вторая строка это перловая однострочкая программка, имитирующая запускаемый нами процесс. Она выводит строку, ждет немного, выводит вторую строку. Магическое $|++ в этом скрипте отключает буферирование вывода, без него весь вывод скрипта выводился бы уже после ожидания.

Третья строка опять на Perl но это уже наше решение. Конечно вместо него мог бы быть тривиальный вызов grep. Но стандартный grep выведет на экран только совпадающие с шаблоном строки, а мне хотелось бы видеть весь вывод.

Эта простейшая программа на Perl выходит с успехом если находит строку, или с неуспехом, если нет. В общем делает ровно то же, что и grep но выводит весь вход на экран.

Ну и постандартному соглашению pipe в Linux, если у нас исходное приложение разрушает pipe (создаваемый символом | то у нас все рушится до конца этой “трубы” с ошибкой).

Как установить timeout в MacOS

В MacOS исходно нет timeout и многих других приложений Linux.

Чтобы исправить эту несправедливость используйте этот рецепт.

Обратите внимание что после этого дополнительные Linux приложения появятся у вас с префиксомg, например gtimeout. Если вам удобнее такие же имена, как в Linux, вам надо поправить PATH в вашем ~/.bashrc. Как это сделать описано на той же страничке с рецептом homebrew.