22

I ran my crontab job 0 2 */1 * * /aScript >aLog.log 2>&1 as a 'root' user, and however I found the env is different from env of the 'root' user, and therefore experiencing a different runtime behavior of my scripts.

An attempt fix was placing export commands in rc.d files, but it still didn't show up! I end up placing export commands in the aScript itself.

My question is that is there a better way to approach this problem? and why env is missing even though it is from the same user 'root' ? (I modifies crontab by running 'crontab -e' from the root)

  • 8
    Cron always runs with a mostly empty environment. HOME, LOGNAME, and SHELL are set; and a very limited PATH. If you do not want to set all the variables yourself, you may be able to source your (bash) profile. – cyberx86 Dec 5 '11 at 6:18
  • 2
    @cyberx86: Why not write that up as an answer and get rep ? – user9517 Dec 5 '11 at 8:16
  • 2
    @Iain: rep is always welcome - but sometimes it feels like a one line answer doesn't really earn the rep. I fully accept that a succinct answer has its place, but I have been (perhaps incorrectly) using comments as an 'easy way out' when I wanted to provide some assistance, but not write up a full, detailed explanation (it was 1am...). I will however take your advice and expand on this one a bit and add it as an answer. – cyberx86 Dec 5 '11 at 21:17
  • @cyberx86: Better to have a correct one liner than incorrect or nothing. – user9517 Dec 5 '11 at 21:20
33

Cron always runs with a mostly empty environment. HOME, LOGNAME, and SHELL are set; and a very limited PATH. It is therefore advisable to use complete paths to executables, and export any variables you need in your script when using cron.

There are several approaches you can use to set your environment variables in cron, but they all amount to setting it in your script.

Approach 1:

Set each variable you need manually in your script.

Approach 2:

Source your profile:

. $HOME/.bash_profile (or . $HOME/.profile)

(You will usually find that the above file will source other files (e.g. ~/.bashrc --> /etc/bashrc --> /etc/profile.d/*) - if not, you can source those as well.)

Approach 3:

Save your environment variables to a file (run as the desired user):

env > /path/to/my_env.sh

Then import via your cron script:

env - `cat /path/to/my_env.sh` /bin/sh

Approach 4:

In some cases, you can set global cron variables in /etc/default/cron. There is an element of risk to this however, as these will be set for all cron jobs.

  • Approach 2 is best for servers where you have sensitive things that shouldn't hit disk in env vars -- passwords, api keys, etc. Worked wonders for me, so thanks. – a p Nov 2 '17 at 21:57
  • Approach 4 worked for me in docker environment where the docker engine sets env vars. For this to work though, I had to save my env in the docker entrypoint. The complete solution is here: github.com/rayyanqcri/swarm-scheduler – hammady Nov 3 '17 at 5:02
  • Could you elaborate on approach 3 for me? When I try to import it I get bash: SHELL=/bin/bash: No such file – KuboMD Jul 16 '19 at 14:24
1

Cron creates its OWN shell with the use specified through which it will run.

So, if you want to keep the same variable of your user, then try to run it with your own user, instead of root or any other user.

Or

The best way is that export those variables in your own script.

1

In RedHat CentOS, you could set /etc/rc.d/init.d/functions default PATH to permanently set. /etc/rc.d/crond calls functions when starts.

0

I had a similar issue on my AWS. Figured it out like that

which python3

gave me /usr/bin/local/python3 location

and then

. $HOME/.profile; /usr/local/bin/python3 /home/ubuntu/your_script.py

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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