fro*_*age 5 startup scripts upstart init events
如何编写保证每次启动后仅运行一次但也保证在至少两个其他作业之一开始运行之前运行完成的 Upstart 任务。我不想更改另外两个作业的 Upstart init 文件,因为它们不属于我。重新启动这两个其他作业中的任何一个都不应该导致所需的任务再次运行。
情况是所需的任务必须对本地文件系统中的某些文件进行一些修改,而其他两个作业都需要这些文件。
我对 Upstart 完全陌生,发现它的学习曲线比我预期的要陡峭,因此有关解决方案为何有效的教育将与解决方案本身一样有价值。
我相信我对自己的问题有一个答案,该答案利用了CameronNemo 的部分解决方案和Mark Russell对相关但有些不同问题的答案。
需要两个 Upstart 配置文件。第一个是本地文件系统可用时立即启动的作业,作为预启动脚本执行所需的文件修改,然后永远处于空闲运行状态:
# modify-files - Single-execution file modification job
start on local-filesystems
console log
pre-start script
echo "$(date --rfc-3339=ns) $(hostname) $UPSTART_JOB"
exec /path/to/your/script
end script
Run Code Online (Sandbox Code Playgroud)
第二个配置文件是一个 Upstart 任务,它会延迟可能依赖于我们尝试修改的文件的所有其他作业的启动。它为每个依赖作业生成一个自身实例:
# modify-files-wait - Helper task for modify-files
start on (starting jobA or jobB)
stop on (started modify-files or stopped modify-files)
instance $JOB
console log
normal exit 0 2
task
script
echo "$(date --rfc-3339=ns) $(hostname) $UPSTART_JOB ($UPSTART_INSTANCE)"
status modify-files | grep -q "start/running" && exit 0
start modify-files || true
sleep infinity
end script
Run Code Online (Sandbox Code Playgroud)
Upstart 将杀死所有在其运行状态下处于空闲状态的modify-files-wait
实例modify-files
。这条normal exit
线解释了它在无限睡眠期间被杀死的可能性。我们需要该task
行来阻止 jobA 和 joB 直到达到停止状态。modify-files
如果尚未启动,则先运行的实例将启动。
由于modify-files
永远不会达到停止状态,因此无论 jobA 或 jobB 是否重新启动,它都不会重新运行。
这个解决方案似乎有效,但我欢迎任何批评或改进。