简体   繁体   English

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

[英]Can upstart's “service start” be used inside a cron job?

TLDR ; TLDR ; Is it possible to create a cron job that runs service service_name start ? 是否可以创建运行service service_name start的cron作业? How? 怎么样?

Content of my 我的内容

sudo crontab -e

is: 是:

45 23 * * * service bormarise_celery_daemon start

This runs normally on terminal as root or server: 这在终端上以root或服务器正常运行:

service bormarise_celery_daemon start
start: Job is already running: bormarise_celery_daemon

But cron gave the following error instead: 但是cron反而给出了以下错误:

bormarise_celery_daemon: unrecognized service

tl;dr TL;博士

You need to add /sbin to cron's PATH so the service script can find initctl . 您需要将/sbin添加到cron的PATH以便service脚本可以找到initctl To do that, add a definition like this to the top of your crontab: 为此,请将此类定义添加到crontab的顶部:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

You may still run into issues with cron emailing you since initctl exits with status 1 (fail) if the job you try to start is already running. 您可能仍会遇到cron通过电子邮件发送问题的问题,因为如果您尝试启动的作业已在运行,则initctl退出状态1(失败)。 You could get around that with something like: 你可以通过以下方式解决这个问题:

45 23 * * * service bormarise_celery_daemon status | grep -q running || service bormarise_celery_daemon start

Despite being a bit long, it should only try to run the start command if the bormarise_celery_daemon service isn't running. 尽管有点长,但是如果bormarise_celery_daemon服务没有运行,它应该只尝试运行start命令。

service vs initctl service vs initctl

While the service command makes an attempt to manage Upstart jobs, it is not the actual Upstart control function -- that would be initctl and the related suite of short-hand commands ( ie , start , stop , etc. ). 虽然service命令尝试管理Upstart作业,但它不是实际的Upstart控制功能 - 它将是initctl和相关的一组简写命令( startstop )。 All of the Upstart scripts reside in /sbin/ . 所有Upstart脚本都位于/sbin/

The service command tries to facilitate people spreading services between both Upstart and classic SysV-style scripts. service命令试图促进人们在Upstart和经典SysV样式脚本之间传播服务。 That way you can use one interface (the service script) to manage services from both systems. 这样,您可以使用一个接口( service脚本)来管理来自两个系统的服务。

Delving into the service Script 深入研究服务脚本

If you browse the actual source of the service script (it's just a Bash script) on Ubuntu 14.04, you'll see: 如果你在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

The opening conditional: 开放条件:

  1. Checks if the service you specified (in your case: bormarise_celery_daemon ) is an Upstart job. 检查您指定的服务(在您的情况下: bormarise_celery_daemon )是否为Upstart作业。 Upstart jobs go into /etc/init/ with a .conf extension. Upstart作业进入/etc/init/ ,扩展名为.conf
  2. If it is, the service script will check to see if it can run initctl . 如果是, service脚本将检查它是否可以运行initctl
  3. If it can, the service script will then make sure that initctl is a new-enough version. 如果可以, service脚本将确保initctl是一个足够新的版本。

If all of that is true, then the service script will try to use the appropriate initctl command to run the Upstart job. 如果所有这些都是真的,那么service脚本将尝试使用适当的initctl命令来运行Upstart作业。 For example: 例如:

service bormarise_celery_daemon start

translates into: 翻译成:

start bormarise_celery_daemon

which is (basically) equivalent to: 这基本上相当于:

initctl start bormarise_celery_daemon

However , if any of those conditions is not true, the service script assumes you're trying to run a SysV-style script. 但是 ,如果这些条件中的任何一个不成立,则service脚本假定您正在尝试运行SysV样式的脚本。 These are just Bash scripts located in /etc/init.d/ . 这些只是位于/etc/init.d/ Bash脚本。 However, if no such script exists, it will exit with the unrecognized service error message. 但是,如果不存在此类脚本,则它将以unrecognized service错误消息退出。

Putting the Pieces Together 把碎片放在一起

The default PATH for cron only contains /bin/ and /usr/bin/ . cron的默认PATH仅包含/bin//usr/bin/ This means it doesn't include /sbin/ which is where the initctl executable is. 这意味着它不包含/sbin/ ,它是initctl可执行文件所在的位置。 This means cron will not be able to run initctl . 这意味着cron将无法运行initctl

When cron runs your crontab, the service script is able to find your Upstart job, but it is not able to run the initctl command, so it skips over trying to run your service via Upstart ( ie , initctl ). cron运行你的crontab,该service的脚本能找到你新贵工作,但它不能运行initctl命令,所以它跳过尝试通过新贵( 运行服务initctl )。 Instead, it then tries to look for a SysV-style script in /etc/init.d/ . 相反,它然后尝试在/etc/init.d/查找SysV样式的脚本。 Since that script doesn't exist, the service script gives up and prints your error message. 由于该脚本不存在, service脚本会放弃并打印您的错误消息。

If you override cron 's default PATH with one including /sbin/ , then the service script will be able to find initctl and will attempt to launch your Upstart job. 如果使用包含/sbin/一个覆盖cron的默认PATH ,则service脚本将能够找到initctl并尝试启动Upstart作业。


Interestingly, on Ubuntu 12.04 the service script only checks to see if an Upstart job exists, omitting both initctl checks. 有趣的是,在Ubuntu 12.04上, service脚本仅检查是否存在Upstart作业,省略两个initctl检查。 That means if you were trying this on Ubuntu 12.04, it would attempt to use Upstart to start your service. 这意味着如果你在Ubuntu 12.04上尝试这个,它会尝试使用Upstart来启动你的服务。 However, if /sbin/ isn't on the path, it would fail with a (slightly) more intelligible error message: 但是,如果/sbin/不在路径上,它将失败并显示(稍微)更容易理解的错误消息:

/usr/bin/service: 123: exec: start: not found

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM