crontab PATH and USER

Solution 1:

According to "man 5 crontab" you can set environment variables in your crontab, by writing them before your cron lines.

There is also an example of a crontab so you just have to copy/paste it :

$ man 5 crontab | grep -C5 PATH | tail 
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow usercommand
17 * * * *  root  cd / && run-parts --report /etc/cron.hourly
25 6 * * *  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )

So you can adjust your PATH or any environment variable to whatever you want. But this example seems enough for typical cases.

Solution 2:

In *ix, processes commonly inherit an environment from their parent process across fork+exec. They have the option of clearing the environment, but usually they don't. You can see the process tree with ps axf, and you can see the environment variables by using ps axfe.

cron is commonly not a child of someone's shell, so it'll often have a different environment from your interactive shell. There's a good chance cron's going to be intentionally clearing its own environment somehow for consistency though.

I like to test my cron jobs ("foo" for the sake of discussion) with the following in an interactive shell: env - ./foo This will actually clear out more env vars that cron does, but it makes it easier to get things going IMO, since what you're testing is more similar. You'll need to set any variables you're depending on (like $PATH), or replace them with something else - EG $USER becomes $(whoami).

I also like to write my bash scripts to use "set -eu" and "set -o pipefail". The -eu says "exit on a nonzero exit code, and exit on an undefined variable reference", and the pipefail says "don't return the last exit code in a pipeline, instead return the first exit code that's nonzero in a pipeline". In your case, the set -u might be particularly helpful.

Solution 3:

Remember crontab is a daemon or service, so is not like a user logged in or something. If you want to have your environment variables you will need to set them yourself. However, most of these variables are set by the shell from the /etc/profile path and then going into your custom variables into your $HOME directory.

You may be able to set some of them by "sourcing" your /etc/profile like:

41 11 * * * /home/<me>/cron_env.sh
Where cron_env.sh will contain something like:
#!/bin/sh
source /etc/profile
/usr/bin/env > /home/<me>/cron_env.log

Solution 4:

In our environment, we typically don't have this issue as root is the only cron allowed and each command is typically ran as an application specific user VIA a su -c command as:

su - myuser -c "/usr/local/scripts/app.sh" 2>&1

since the "-" option is specified we get myuser's profile and environment. We recently had an issue with a command that needed root's authority to complete successfully, so we just issued the command without the su -c. After some amount of research, it dawned on us that the easiest way to get root's environment is to use the same technique for root as we do for all other applications so we issued:

su - root -c "/usr/local/scripts/app.sh" 2>&1

Solution 5:

crontab is not a bash script, you can't use environment variables that are normally available in a shell.

Try moving all that code into a shebang'ed script file (one starting with the line "#!/bin/bash") and run that script in the crontab.

I'm not sure, but i think PATH (and maybe EMAIL if you set it) may be the only one you can access inside the crontab file .

EDIT: Check the crontab 5 man page, there quite a few environment variables aviable, all set by the cron daemon.