How can I load the users environment variables in a cronjob?
I have a cronjob which should start a script every minute on my Ubuntu machine:
* * * * * /home/user/myscript.sh;
In this script I want to use environment variables like $JAVA_HOME
and $M2_HOME
to automatically start a build process. The problem is that those variables are set in the .bashrc
via export JAVA_HOME=/../..
.
Therefore I source
these files before executing my script:
* * * * * source ~/.bash_profile; source ~/.bashrc; /home/user/myscript.sh;
However, the variables aren't set! To test this I echo
the environment variables via env
to a log file:
env >> ~/env.log
echo $M2_HOME >> ~/env.log
The log file still doesn't contain the variables. Only the following are appended to the file (no $M2_HOME
etc.):
LANGUAGE=en_US:en
HOME=/home/user
LOGNAME=user
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/user
If I run the script right in my shell all of the variables are print out to env.log
.
The same happens when I put the source
commands into the script file. Only if I remove the export
keyword before the declaration of the variable it is visible by the echo $var
command. But this is not a solution because I don't manage these declarations.
I tried the solution of @tripplee with the limited sh shell problem, but it still doesn't work. I further reduced it to a very simple cronjob without a second script to show the problematic:
* * * * * . $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log;
cat /home/user/env.log
:
LANGUAGE=en_US:en
HOME=/home/user
LOGNAME=user
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/user
Best Answer
The cron job syntax is restricted to
sh
only so you cannot use Bashisms like~
. Fortunately, the fix is easy -- just replace it with$HOME
. Similarly,source
needs to be replaced with.
(just a dot).Of course, the scripts you source mustn't use Bash syntax either if you intend to use them from
sh
. Probably the easiest fix is to migrate these things to your script (or create a wrapper script for Cron to run).Because inside your script, you can use
bash
if you like, provided of course that the shebang line is correctly#!/bin/bash
(adjust the path if you have to) rather than#!/bin/sh
.If you don't like that for some reason, you can inline Bash in your
crontab
file by specifying it explicitly:You should be able to see
source: command not found
andexport: command not found
in the emails sent bycron
when things go wrong. Examining the error output is really important for troubleshooting.Of course, if you have the standard
.bashrc
on Ubuntu, it will bail out immediately if you try to source it from a noninteractive script. Maybe better then to put the settings you want in a noninteractive use in another file (maybe.profile
which will be read bysh
by default)?