Я смотрю на сценарий init.d, написанный предыдущим коллегой, который сейчас работает некорректно. Он работает на centos-6
После некоторых экспериментов я нашел причину проблемы. Он написал сценарий, чтобы ждать до 30 секунд, пока команда kill -TERM не запустится, прежде чем сообщать об ошибке. Для этого он запускает команду:
kill -0 $pid
, чтобы проверить, умерла ли убитая программа.
Команда kill -0 выдает ошибку:
/etc/init.d/celerybeat line 211: kill (<pid>) - No such process
она существует сразу после сбоя этой строки.
Это то, что я ожидал от set -e, но сценарий не запускает set -e. Фактически, в ней есть закомментированная строка с комментарием, в котором говорится, что команда kill -0 завершится ошибкой, если она установлена, поэтому он прекрасно понимал, что не хочет, чтобы она была установлена.
Это происходит, скорее, я запускаю его через службу или запускаю сценарий напрямую из каталога /etc/init.d
Итак .. почему сценарий работает так, как если бы установлен set -e? и, что более важно, как мне предотвратить его запуск таким образом или переписать строку, чтобы проверить, работает ли pid, не вызывая исключения?
Вы можете отключить «выход при ошибке» с помощью set +e
или set +o errexit
или запустить команду в условном выражении, чтобы выход из ошибки не применялся. Проще всего было бы:
somecmd... || true
Но это уничтожит возвращаемое значение, а оно вам, вероятно, понадобится, так как kill -0
мало что делает, кроме его установки. Так что, может быть, что-то вроде этого:
if kill -0 "$pid" 2>/dev/null ; then
echo it lives
fi
Что касается «почему», я думаю, что CentOS 6 запускает Upstart, и по крайней мере в документации по Ubuntu утверждается, что Upstart запускает сценарии с включенным set -e
.