新兴的“服务开始”可以在一个cron工作中使用吗?

TLDR ; 是否有可能创build一个运行服务 service_name 启动cron作业? 怎么样?

我的内容

sudo crontab -e 

是:

 45 23 * * * service bormarise_celery_daemon start 

这作为根或服务器在terminal上正常运行:

 service bormarise_celery_daemon start start: Job is already running: bormarise_celery_daemon 

但是cron反而给出了下面的错误:

 bormarise_celery_daemon: unrecognized service 

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服务没有运行,它应该只尝试运行start命令。

服务vs initctl

虽然service命令尝试管理Upstart作业,但它不是实际的Upstart控制函数 – 这将是initctl和相关的一组短命令( startstop )。 所有的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 

开放条件:

  1. 检查你指定的服务(你的情况是: bormarise_celery_daemon )是不是Upstart工作。 Upstart作业进入/etc/init/扩展名为.conf
  2. 如果是, service脚本将检查它是否可以运行initctl
  3. 如果可以, 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