我有一个非常好用的脚本,可以在 /etc/init.d 中使用。事实上,我有很多这样的脚本,都是用 Tanuki Java Service Wrapper 创建的。
在我看来,可能存在一个简单的模板,用于将这样的 shell 脚本包装成 upstart 脚本,但经过一番谷歌搜索并没有找到。
我是否遗漏了什么?
答案1
我不记得看到过这样的模板。不过,有点讽刺的是,从技术上讲,由于向后兼容作业 rc 和 rcS,upstart 首先启动了您的 init.d 脚本。
我会考虑重写你所拥有的一切作为一项新工作,但是,我知道有些脚本很难转换,所以这里是我在一些脚本上做了一段时间的事情:
description "xyz"
author "xyz"
start on runlevel 5
stop on runlevel [!5]
pre-start script
# do my work here to start the service
end script
post-stop script
# do work here to stop the service
end script
现在,根据服务的性质,无论它是持久化还是自行分叉,您都可能需要添加expect fork
或添加task
到作业文件中。
只是为了完成这个想法,通常,这就是完整的 upstart 作业文件的全部内容。所有启动前的工作都已完成,所有清理工作都已完成,唯一剩下的就是服务本身,通常会添加以下内容:
exec service_cmd
答案2
所以 upstart 作业的一点就是编写起来简单。
init.d 脚本中有很多反复出现的 shell 脚本魔法。Case 语句、pidfile 跟踪、lsb 注释行。如果不读过 init.d 脚本,就很难知道如何编写一个好的脚本。
如果您已经不辞辛劳写完了所有这些内容,那么您就不需要新贵的工作了,除非如我在另一条评论中提到的那样,您依赖于另一个新贵的工作/事件。
但实际上,upstart 确实让事情变得非常简单。除非您需要设置 tmpdirs、ulimits 或运行时参数等内容,否则您不需要预启动。除非您想确保在服务结束后进行整理(服务在正常退出时确实应该自行清理),否则您不需要后停止。
通常,一个包含许多选项的大型 init.d 脚本可以归结为 10 - 15 行的 upstart 作业。最复杂的 init.d 脚本可以将其大部分逻辑转储到预启动中。关键在于它只是一小段代码来设置进程的环境,而不是处理启动/停止/重生等的逻辑。
最难的部分,也是人们最常犯错的部分,是知道何时开始/停止他们的工作。这start on runlevel [2345]
似乎合乎逻辑,但却忽略了网络在那时并行启动的事实,本地文件系统挂载也是如此。关键是尝试找出运行所需的最少东西(其他服务、文件系统、网络等),并在完成这些操作后启动。大多数传统网络服务都应该这样做start on (local-filesystems and net-device-up IFACE!=lo)
。
答案3
我认为 Upstart 保持了与 SysV 样式 init 脚本的向后兼容性/etc/init.d
。您应该能够不加改变地使用 init 脚本。