mandag 12. september 2016

Crontab, environment and BASH_ENV

Automation with cron-jobs is an often performed task. But cron-jobs are started in a specialized environment and this makes it often difficult to test them. And the cron-environment can only be configured globally. A users standard environment is often given by a .profile or .bashrc file, which cron simply ignores since it uses a non-interactive non-login shell.

One solution is to write the environment before starting the job, like
  00 01 * * * PATH=.:$PATH myjob
which gets cumbersome with many jobs and many parameters.

A better solution is to  store all environment settings into one file like /home/mine/.my_env and source it from there:
  00 01 * * * . /home/mine/.my_env; myjob
This works well, but it's an additional command before every job.

The bash-shell has a nice environment-variable named BASH_ENV which it will read automatically when the shell is named bash and the shell is non-interactive, e.g.
  SHELL=/bin/bash
  BASH_ENV=/home/mine/.my_env
  00 01 * * * myjob
This works under debian/ubuntu, no extra code needed for new jobs. It might not work everywhere, since some cron-environments don't allow setting environment variables like BASH_ENV.

But one will still not have ones default environment. One will get the settings from .my_env. The obvious solution like using the existing .bashrc doesn't work since those start by default with:
  # If not running interactively, don't do anything
  [ -z "$PS1" ] && return

and wouldn't load the environment when run from cron. But one can easily put all the environments settings into a file and source that file from both .bashrc as
  . /home/mine/.my_env
and from cron-jobs with BASH_ENV as shown above.