Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have written various scripts to launch Java server applications, which are typically run for 24 hours before being shut down (by invoking the same script with a different parameter).

The script relies on environment variables defined in a file: ~/<user>.env, which I source from .bashrc.

This works fine when invoking the script from the command line but if I want to add the script as a crontab entry I run into the problem where .bashrc isn't read.

My question: What is the best practice approach for solving this problem? I realise I could define a crontab entry such as:

* * * * 1-5 /usr/bin/bash -c '. /home/myuser/myuser.env && /home/myuser/scripts/myscript.sh'

... but this seems plain ugly. Alternatively I could source myuser.env at the beginning of every script, but this would become a nightmare to maintain.

Any help appreciated.

share|improve this question
    
Those are the two options I would suggest. –  einstiien Feb 19 '10 at 17:35
add comment

5 Answers

I usually address this with a short cron wrapper script:

#!/bin/bash
[ -r $HOME/.bashrc ] && . $HOME/.bashrc
[ -r $HOME/.profile ] && . $HOME/.profile
exec "$@"

Then just prefix the command in crontab with your wrapper:

* * * * 1-5 ~/scripts/cron-wrapper ~/scripts/myscript.sh
* * * * 1-5 ~/scripts/cron-wrapper ~/scripts/myotherscript.sh

Some versions of cron allow you to set variables directly in crontab. Unfortunately, I don't get to use those at work.

share|improve this answer
add comment
up vote 5 down vote accepted

I actually discovered a fairly elegant solution by adding the '-l' (--login) flag to my bash command, which causes it to source all login files, including .bashrc. Hence my crontab command is simply:

* * * * 1-5 /usr/bin/bash -lc '/mnt/group/core/deploy/scripts/test.sh' > /dev/null 2>&1
share|improve this answer
add comment

An alternative (although not necessarily better) option would be to add these into root's crontab, and have the entry use su with a dash to become the user in question. The environment variables would then be pulled in automatically via the user's default shell environment in ~/.bashrc, or the like. eg:

* * * * 1-5 su - scriptuser '/home/myuser/scripts/myscript.sh' This would run the job as scriptuser, with all the environment variables of a proper login. The downside is that scriptuser himself couldn't set this job up -- it would require root privileges to do that.

share|improve this answer
add comment

cron-wrapper solution worked for me with one modification, I needed to replace the $HOME with the absolute path to the user home folder, in this case it was:

#!/bin/bash
[ -r /root/.bashrc ] && . /root/.bashrc
[ -r /root/.profile ] && . /root/.profile
exec "$@"
share|improve this answer
add comment

The only other thing I can think of would be based on:

bash -i --rcfile 'init' -c 'script'

which is probably less attractive.

share|improve this answer
    
I actually tried this and it doesn't work. According to the GNU bash manual, --rcfile "Execute commands from filename (instead of ~/.bashrc) in an interactive shell.", and as I'm not running an interactive shell I presume this is why it's failing. –  Adamski Feb 25 '10 at 10:56
    
@Adamski: The -i makes the shell think it's interactive. –  Dennis Williamson Feb 25 '10 at 13:38
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.