views:

328

answers:

3

Forgive my ignorance, but I am somewhat new to shell scripting and the use of environment variables in Linux.

I have a script that performs a backup of a MySQL database. I have the following lines in the script that are used to log a successful dump of the database:

output=`date; echo "Database export successful from $ENV_HOSTNAME to $BACKUP_HOSTNAME"`
echo $output >> /var/log/errorLog

I have the variables (ENV_HOSTNAME and BACKUP_HOSTNAME) defined in /etc/profile as follows:

export ENV_HOSTNAME="env1.somename.com"
export BACKUP_HOSTNAME="env2.somename.com"

I can see these variables listed when I call printenv and the variable values appear in the log file correctly when I run this script (as root). However, when I set this script to run using cron, the variable values are not appearing in the log file. I know that script runs because I can see the date and the rest of string, but the variables are blank:

Fri Nov 6 22:31:05 EST 2009 Database export successful from to

I'm sure I am missing something simple here, so thank you in advance for the help.

+2  A: 

The shell cron uses to run your jobs is not interactive, so it does not automatically source /etc/profile or similar files.

One trivial solution would be to simply add

. /etc/profile

at the start of your script.

ephemient
+5  A: 

There's your problem: cron doesn't run /etc/profile.

cron is started with only a tiny number of environment settings; anything else you need, you have to set up yourself, so it's customary to have cron call a script to handle the setup and then the main action.

Carl Smotricz
I usually like this better than just blindly running your profile - each cron job should be totally responsible for setting up its environment. Your cron jobs should run with what they need *and nothing more*. This makes debugging a lot easier in my opinion (you can always put a "env >/tmp/cron.env" in your script to see what it's running with).
paxdiablo
+4  A: 

G'day,

When cron executes it only gives you a minimal set of env. vars.

One trick is to create a shell script containing the variables you want to set and then have all of your cron scripts source that script when they start.

For example, add the following at the top of the cron script you are running.

. my_cronenv.sh

Your shell script my_cronenv.sh should export all of the variables you want to set for your cron jobs.

Edit: Forgot to say that one other big advantage of this is that you only need to change one script if there's a change to the environment that you are running your cronjobs in rather than having to search through a bunch of cron scripts to make the same edit.

One other thing is it's a good idea to get into the habit of always referring to your env. vars using braces. for example, ${ENV_HOSTNAME} rather than $ENV_HOSTNAME.

Getting into this habit means you won't get caught out when you use the value of an environment variable. For example, ${ENV_HOSTNAME}_RSV would expand as you expect as opposed to $ENV_HOSTNAME_RSV which won't. N.B. On some systems a single letter variable would work as expected without the braces but I find it better to just get in the habit. It also makes your intent clear to any future reader of your shell scripts.

cheers,

Rob Wells
@Rob Wells: Thanks for the tip. I really appreciate the help.
shambleh