我有以下针对在 Ubuntu 14.04 上运行的 upstart 服务的测试配置文件:
expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
script
ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 }" > /tmp/upstart_test.log
end script
嵌入的 ruby 脚本只是休眠 5 秒钟(模拟加载),然后向自己发送一个 STOP 信号,以通知 Upstart 它已准备就绪,然后打印几次“正在运行”(模拟某些服务正在发生)。哇,太棒了。这么简单。
问题是,当我用启动此“服务”时start fake-service
,该命令挂起(等待服务完成启动),并且该过程最终处于停止状态,而 Upstart 永远不会确认或发送“CONT”。
是什么赋予了??
更新:exec 有帮助,但分叉仍然失败
我发现,如果在配置文件中使用 exec 而不是脚本块来运行启动“守护进程”的命令,它可以正常工作:
expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
exec ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 }" > /tmp/upstart_test.log
但是,如果我在脚本中包含一个 fork (expect stop
我首先想到的就是使用它的全部目的 - 帮助 Upstart 轻松确定主进程 PID):
expect stop
chdir /home/joe/Projects/Marketplace
env RAILS_ENV="development"
exec ruby -e "STDOUT.sync=true; puts 'loading...'; sleep 5; fork { Process.kill(:STOP, Process.pid); 5.times { puts 'running'; sleep 3 } }; Process.wait" > /tmp/upstart_test.log
Upstart 文档确实有关于将 expect 与脚本块一起使用的警告,但它具体谈到了在块中运行多个命令会出现问题,因为它不知道要监视哪个命令。在这种情况下,我只运行一个命令……所以这没有帮助。
答案1
事实证明,我对 的理解expect stop
是错误的!我认为,正如我上面所述,它(像其他expect
节一样)被用来“帮助 Upstart 轻松确定主进程 PID”。
现在我重新阅读了文档,我相信它的意思,其中说,“指定作业的主进程将发出 SIGSTOP 信号以表明它已准备就绪”,是指原来的由 upstart 运行的进程必须发出 STOP 信号,并且该信号用于仅有的确定作业何时准备就绪。因此,此expect
节与其他两节无关,后两节用于确定包含分支的作业的主 PID。
它对脚本块不起作用的原因是脚本块本身会分叉一个新的 shell 来运行其内容,因此主进程实际上是块内运行的任何命令的父进程。
现在一切都变得更有意义了:)