tl;博士
您需要将/sbin 添加到cron 的PATH 以便service 脚本可以找到initctl。为此,请在 crontab 顶部添加如下定义:
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
如果您尝试启动的作业已经在运行,您可能仍会遇到cron 向您发送电子邮件的问题,因为initctl 以状态 1(失败)退出。您可以通过以下方式解决此问题:
45 23 * * * service bormarise_celery_daemon status | grep -q running || service bormarise_celery_daemon start
尽管有点长,但它应该只在bormarise_celery_daemon 服务未运行时尝试运行启动命令。
服务与 initctl
虽然service 命令尝试管理 Upstart 作业,但它不是实际的 Upstart 控制功能——这将是 initctl 和相关的速记命令套件(即、start、stop、等)。所有 Upstart 脚本都位于 /sbin/。
service 命令试图帮助人们在 Upstart 和经典 SysV 样式脚本之间传播服务。这样您就可以使用一个界面(service 脚本)来管理来自两个系统的服务。
深入研究服务脚本
如果您在 Ubuntu 14.04 上浏览 service 脚本(它只是一个 Bash 脚本)的实际源代码,您会看到:
if [ -r "/etc/init/${SERVICE}.conf" ] && which initctl >/dev/null \
&& initctl version | grep -q upstart
then
# Upstart configuration exists for this job and we're running on upstart
case "${ACTION}" in
start|stop|status|reload)
# Action is a valid upstart action
exec ${ACTION} ${SERVICE} ${OPTIONS}
;;
restart)
# Map restart to the usual sysvinit behavior.
stop ${SERVICE} ${OPTIONS} || :
exec start ${SERVICE} ${OPTIONS}
;;
force-reload)
# Upstart just uses reload for force-reload
exec reload ${SERVICE} ${OPTIONS}
;;
esac
fi
开场条件:
- 检查您指定的服务(在您的情况下为:
bormarise_celery_daemon)是否是 Upstart 作业。新贵职位进入/etc/init/,扩展名为.conf。
- 如果是,
service 脚本将检查它是否可以运行 initctl。
- 如果可以,
service 脚本将确保 initctl 是一个足够新的版本。
如果这一切都是真的,那么service 脚本将尝试使用适当的initctl 命令来运行Upstart 作业。例如:
service bormarise_celery_daemon start
翻译成:
start bormarise_celery_daemon
这(基本上)相当于:
initctl start bormarise_celery_daemon
但是,如果其中任何一个条件不成立,service 脚本会假定您正在尝试运行 SysV 样式的脚本。这些只是位于/etc/init.d/ 中的 Bash 脚本。但是,如果不存在这样的脚本,它将退出并显示unrecognized service 错误消息。
拼凑起来
cron 的默认PATH 仅包含/bin/ 和/usr/bin/。这意味着它不包括/sbin/,这是initctl 可执行文件所在的位置。 这意味着cron 将无法运行initctl。
当cron 运行您的 crontab 时,service 脚本 能够找到您的 Upstart 工作,但它不能 运行 initctl 命令,因此它会跳过尝试通过 Upstart 运行您的服务(即,initctl)。相反,它会尝试在 /etc/init.d/ 中查找 SysV 样式的脚本。由于该脚本不存在,service 脚本放弃并打印您的错误消息。
如果您用包含/sbin/ 的一个覆盖cron 的默认PATH,则service 脚本将能够找到initctl 并尝试启动您的Upstart 作业。
有趣的是,在 Ubuntu 12.04 上,service 脚本仅检查是否存在 Upstart 作业,而忽略了两个 initctl 检查。这意味着如果你在 Ubuntu 12.04 上尝试这个,它会尝试使用 Upstart 来启动你的服务。但是,如果/sbin/ 不在路径上,它会失败并显示(稍微)更容易理解的错误消息:
/usr/bin/service: 123: exec: start: not found