TLDR; Is it possible to create a cron job that runs service service_name start? How?
Content of my
sudo crontab -e
is:
45 23 * * * service bormarise_celery_daemon start
This runs normally on terminal as root or server:
service bormarise_celery_daemon start
start: Job is already running: bormarise_celery_daemon
But cron gave the following error instead:
bormarise_celery_daemon: unrecognized service
A few problems with cron: Smallest resolution is 1 minute—If a task needs to run every 30 seconds, you can't do it with cron. Error handling—If a job fails, what should happen? Solutions have been built to solve this single problem. Developers love adding more band-aids rather than admitting there is a better way.
What does * mean in Cron? The asterisk * is used as a wildcard in Cron. * sets the execution of a task to any minute, hour, day, weekday, or month.
No. As long as you use the crontab -e command to edit the file, when you save it, you'll get a 'New Crontab Installed' message.
Cron jobs are typically located in the spool directories. They are stored in tables called crontabs. You can find them in /var/spool/cron/crontabs. The tables contain the cron jobs for all users, except the root user.
You need to add /sbin
to cron's PATH
so the service
script can find initctl
. To do that, add a definition like this to the top of your 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. 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.
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 (i.e., start
, stop
, etc.). All of the Upstart scripts reside in /sbin/
.
The service
command tries to facilitate people spreading services between both Upstart and classic SysV-style scripts. That way you can use one interface (the service
script) to manage services from both systems.
If you browse the actual source of the service
script (it's just a Bash script) on Ubuntu 14.04, you'll see:
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:
bormarise_celery_daemon
) is an Upstart job. Upstart jobs go into /etc/init/
with a .conf
extension.service
script will check to see if it can run initctl
.service
script will then make sure that initctl
is a new-enough version.If all of that is true, then the service
script will try to use the appropriate initctl
command to run the Upstart job. 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. These are just Bash scripts located in /etc/init.d/
. However, if no such script exists, it will exit with the unrecognized service
error message.
The default PATH
for cron only contains /bin/
and /usr/bin/
. This means it doesn't include /sbin/
which is where the initctl
executable is. This means cron
will not be able to run 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 (i.e., initctl
). Instead, it then tries to look for a SysV-style script in /etc/init.d/
. Since that script doesn't exist, the service
script gives up and prints your error message.
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.
Interestingly, on Ubuntu 12.04 the service
script only checks to see if an Upstart job exists, omitting both initctl
checks. That means if you were trying this on Ubuntu 12.04, it would attempt to use Upstart to start your service. However, if /sbin/
isn't on the path, it would fail with a (slightly) more intelligible error message:
/usr/bin/service: 123: exec: start: not found
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With