Как заставить timeout(1) вести себя в cron так же, как в интерактивной оболочке

Как заставить timeout(1) вести себя в cron так же, как в интерактивной оболочке

Выполнение этой команды в интерактивном bash:

$ timeout 1 sleep 2; echo $?
124

возвращается124через 1 секунду, как и ожидалось и как описано в timeout(1).

Однако если я запущу то же самое как задание cron или передам это как командную строку bash, этого не произойдет:

$ bash -c "timeout 1 sleep 2; echo $?"
0

Добавление -iв вызов bash не помогает, как и использование --foregroundпараметра timeout(1). Я также пробовал то же самое с ksh и zsh, но всегда получаю тот же результат, так что я предполагаю, что это должно быть что-то присущее способу работы timeout(1).

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

Есть ли какие-нибудь намеки, как я могу этого добиться? В конечном итоге я хочу запустить команду в cron, которая, скорее всего, заблокируется навсегда, и я хочу надежно обнаружить этот случай.

решение1

Из-за двойных кавычек $?расширяетсядовызывается команда bash. Она заменяется статусом выходапредыдущийкоманда (которая была первой exit $?)

Краткая демонстрация

bash -c 'exit 42'
bash -c "timeout 1 sleep 2; echo $?"   # => 42

Решение состоит в том, чтобы использоватьодинарные кавычкитак что текущий интерактивный процесс bash не расширяет переменную

bash -c 'timeout 1 sleep 2; echo $?'   # => 124

решение2

Вы можете попробовать выполнить команду следующим образом:

bash -c "timeout 1 sleep 2"; echo $?

Связанный контент