Мое новомодное задание перестало работать в предварительном запуске, когда это перемещает любой предыдущий файл журнала в резервное копирование:
pre-start script
mv -f $LOGDIR/$LOGFILE $LOGDIR/$LOGFILE.bak
touch $LOGDIR/$LOGFILE
end script
Я ожидаю mv
перестать работать, если предыдущий файл журнала не существует, так добавило touch
гарантировать, что последняя команда в теле сценария возвращается 0.
Однако, если сценарий работает, когда нет предыдущего файла журнала в каталоге журнала, он перестал работать в предварительном запуске:
Jan 9 17:21:14 ip-172-30-1-54 kernel: [ 250.154908] init: myscript state changed from starting to security
Jan 9 17:21:14 ip-172-30-1-54 kernel: [ 250.154951] init: myscript state changed from security to pre-start
Jan 9 17:21:14 ip-172-30-1-54 kernel: [ 250.155652] init: myscript pre-start process (1425)
Jan 9 17:21:14 ip-172-30-1-54 kernel: [ 250.157167] init: myscript pre-start process (1425) terminated with status 1
Jan 9 17:21:14 ip-172-30-1-54 kernel: [ 250.157280] init: myscript goal changed from start to stop
Если я затем запускаю сценарий снова, он проходит, предварительно запускаются успешно и в основное тело сценария:
Jan 9 17:21:29 ip-172-30-1-54 kernel: [ 265.444327] init: myscript state changed from starting to security
Jan 9 17:21:29 ip-172-30-1-54 kernel: [ 265.444371] init: myscript state changed from security to pre-start
Jan 9 17:21:29 ip-172-30-1-54 kernel: [ 265.445359] init: myscript pre-start process (1431)
Jan 9 17:21:29 ip-172-30-1-54 kernel: [ 265.447203] init: myscript pre-start process (1431) exited normally
Jan 9 17:21:29 ip-172-30-1-54 kernel: [ 265.447249] init: myscript state changed from pre-start to spawned
Jan 9 17:21:29 ip-172-30-1-54 kernel: [ 265.447874] init: myscript main process (1434)
Jan 9 17:21:29 ip-172-30-1-54 kernel: [ 265.447896] init: myscript state changed from spawned to post-start
Jan 9 17:21:29 ip-172-30-1-54 kernel: [ 265.447972] init: myscript state changed from post-start to running
От этого поведения я вывожу, что тело сценария выполняется одна строка за один раз, и любой отказ завершает сценарий (во многом как a make
). Документация script
директива не дает указаний:
Позволяет спецификации многострочного блока кода оболочки выполняться. Блок завершается сценарием конца.
Кто-либо может или подтвердить или отклонить мою веру? Если подтверждено, я могу просто выполнить автономный сценарий оболочки с exec
. Если отклонено, я должен в другом месте искать свою проблему.
У меня создалось впечатление, что Выскочка запустила скрипт в целом с помощью /bin/sh
, с выходом на ошибке (set -e
, или параметр командной строки -e
). Таким образом, если какая-либо команда, код выхода которой не проверяется, возвращает ненулевой код выхода, завершите сценарий сразу.
Действительно, учитывая конфигурацию:
description "Testing upstart"
task
script
set -o > /tmp/blah
end script
Каждый находит следующий набор опций:
Current option settings
errexit on
noglob off
ignoreeof off
interactive off
monitor off
noexec off
stdin off
xtrace off
verbose off
vi off
emacs off
noclobber off
allexport off
notify off
nounset off
nolog off
debug off
Хотя я мистифицирован относительно того, как это работало во второй раз, с тех пор, для любой конфигурации формы:
pre-start script
false
# any number of commands
end script
Ни одна из команд после false
выполнялись, как ожидалось, таким образом, touch
команда никогда не должна была выполняться и mv
должен был перестать работать на последующих выполнениях также.
set -e
весьма обычно - Вы найдете, что, например, скрипты обслуживания пакета также запущены с ним, включил. Именно поэтому Вы видели бы шаблон формы:
command that could fail but is not essential || true
Действительно, в Поваренной книге говорится это также:
Если a
script
раздел, кажется, ведет себя нечетным способом, возможности состоят в том, что одна из команд перестала работать. Помните, что Выскочка выполняет каждыйscript
использование раздела/bin/sh -e
. Это означает, что, если какая-либо простая команда перестала работать, оболочка выйдет.