Raymii.orgQuis custodiet ipsos custodes?
Home | About | All pages | Cluster Status | RSS Feed | Gopher
Better Cron env and shell control with the SHELL variable
Published: 08-03-2013 | Author: shtylman | Text only version of this article
❗ This post is over nine years old. It may no longer be up to date. Opinions may have changed.
Table of Contents
original article from: http://shtylman.com/post/cron-shell-power/ - archived for importance.
I'm developing an open source monitoring app called Leaf Node Monitoring, for windows, linux & android. Go check it out!
Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.
You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $100 credit for 60 days.
If you don't know what cron is this post is not for you.
SHELL variable in cron is more powerful than you may realize.
Most people will have this type of setup in their crontab.
NODE_ENV=production OTHER_VAR=foo */10 * * * * /path/to/node /path/to/my/script.js
If you don't want to repeat
/path/to/node (or your runtime) over and over, you
will add a
PATH variable to go with the other variables.
But what happens if you want to use something like nvm or rvm or virtualenv, etc? It is not uncommon to have the above change to something like the following
*/10 * * * * /path/to/my/launcher.sh */10 * * * * /path/to/my/launcher_another.sh
Now you have several shell scripts which invoke the required commands to setup the environment and then run whatever program.
There is a little known special env variable for cron:
SHELL. Most people know
this variable can be used to change the shell your scripts run run (i.e.
SHELL=/bin/bash), but it can actually run any file!
So lets say I use nvm and want to setup my environment. Instead of making custom launchers for each command, I can simply do the following:
SHELL=/path/to/setup/cron.bash */10 * * * * node $HOME/foo.js
Now lets look at what
cron.bash might look like:
#!/bin/bash set -e source /etc/environment source /etc/profile # setup any env variables you want here export NODE_ENV=production # I use node so I want to add node path stuff via npm # $HOME is available, but not many other env vars are by default source $HOME/nvm/nvm.sh # restore SHELL env var for cron SHELL=/bin/bash # execute the cron command in an actual shell exec /bin/bash --norc "$@"
For the most part it looks just like any other shell script. The important
magical parts are the last 4 lines. These lines put back the SHELL variable to
/bin/bash and then execute a bash shell to run the cronline command (the stuff
for the specific cronjob).
SHELL=/full/path/to/cron.bash MAILTOemail@example.com # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command # dummy cron command to print the environment variables ever minute * * * * * env # node scripts can simply be run using `node` now * * * * * node /path/to/script/.js
Now our cron files have a consistent environment setup and we can simply run whatever commands we need without further PATH tricks or nonsense.
Go forth and update your dirty crontabs!bash , cron , env , nodejs , shell , tutorials , zsh