【问题标题】:Can upstart's "service start" be used inside a cron job?可以在 cron 作业中使用 upstart 的“服务启动”吗?
【发布时间】:2015-06-30 04:06:07
【问题描述】:

TLDR;是否可以创建运行 service 的 cron 作业 service_name 开始?怎么样?

我的内容

sudo crontab -e

是:

45 23 * * * service bormarise_celery_daemon start

这在终端上以 root 或服务器的身份正常运行:

service bormarise_celery_daemon start
start: Job is already running: bormarise_celery_daemon

但是 cron 却给出了以下错误:

bormarise_celery_daemon: unrecognized service

【问题讨论】:

    标签: linux cron upstart


    【解决方案1】:

    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 和相关的速记命令套件(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 作业。新贵职位进入/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
    

    【讨论】:

    • grep -q 与 ||很聪明。直到。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-11-10
    • 2012-01-03
    • 1970-01-01
    • 2014-05-16
    • 2019-05-23
    • 2012-06-30
    • 1970-01-01
    • 2012-11-11
    相关资源
    最近更新 更多