32

Here is my cron job:

plee@dragon:~$ crontab -l
* * * * * /bin/bash -l -c 'source ~/.bashrc; echo $EDITOR > /tmp/cronjob.test'

and inside ~/.bashrc file, I have export EDITOR=vim, but in the final /tmp/cronjob.test file, it's still empty?

So how can I get the environment variables (set in .bashrc file) and use it in my cron job?

plee@dragon:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 12.04 LTS
Release:        12.04
Codename:       precise
plee@dragon:~$ uname -a
Linux dragon 3.2.0-26-generic-pae #41-Ubuntu SMP Thu Jun 14 16:45:14 UTC 2012 i686 i686 i386 GNU/Linux

If use this:

* * * * * /bin/bash -l -c -x 'source ~/.bashrc; echo $EDITOR > /tmp/cronjob.test' 2> /tmp/cron.debug.res

In /tmp/cron.debug.res:

...
++ return 0
+ source /home/plee/.bashrc
++ '[' -z '' ']'
++ return
+ echo

BTW, the .bashrc file is the default one came with Ubuntu 12.04, with the exception that I added one line export EDITOR=vim.

If I don't use the cron job, instead, just directly do this on the command line:

source .bashrc; echo $EDITOR # Output: vim
codeforester
  • 39,467
  • 16
  • 112
  • 140
Peter Lee
  • 12,931
  • 11
  • 73
  • 100
  • what happens if you `cat ~/.bashrc` into a temp file? – Alex Mar 21 '13 at 21:13
  • what do you mean by `cat ~/.bashrc`? It has a line: `export EDITOR=vim`. I'm asking why the `echo` command does NOT pick up the `$EDITOR` environment variable. – Peter Lee Mar 21 '13 at 21:17
  • Sorry for being unclear, in the cron entry, instead of `source`ing the file, use `cat` to confirm that it can be read by `cron`. – Alex Mar 21 '13 at 21:22
  • Yes, it can read `* * * * * /bin/bash -l -c 'cat ~/.bashrc > /tmp/cronjob.test'` – Peter Lee Mar 21 '13 at 21:25
  • I just tried a similar cron command and it worked fine, interpreting ~ correctly and echo'ing the shell variable from ~/.bashrc. Could that suggest there is an error in ~/.bashrc ?? – suspectus Mar 21 '13 at 21:27
  • can you change the crontab entry to: `* * * * * /bin/bash -l -c -x 'source ~/.bashrc; echo $EDITOR > /tmp/cronjob.test' 2> /tmp/cron.debug.res` and post the contents of `/tmp/cron.debug.res` – Alex Mar 21 '13 at 21:31
  • @Alex, the `/tmp/cron.debug.res` exists, but empty. – Peter Lee Mar 21 '13 at 21:37
  • I've edited my question, it was meant to redirect stderr instead of stdin. – Alex Mar 21 '13 at 21:38
  • looks like in your `source ~/.bashrc` `return`s without doing anything if some variable is empty (`[ -z "$something" ]`). I'm not running Ubuntu, can you also post the .bashrc file? – Alex Mar 21 '13 at 21:49

3 Answers3

51

The reason for source ~/.bashrc not working is the contents on your ~/.bashrc (default one from Ubuntu 12.04). If you look in it you will see on lines 5 and 6 the following:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

PS1 variable is set for an interactive shell, so it's absent when run via cron, even though you are executing it as a login shell. This is confirmed by contents of the file produced by /bin/bash -l -c -x 'source ~/.bashrc; echo $EDITOR > /tmp/cronjob.test':

+ source /home/plee/.bashrc
++ '[' -z '' ']'
++ return

To make source ~/.bashrc work, comment out the line that checks for presence of the PS1 variable in ~/.bashrc:

#[ -z "$PS1" ] && return

This will make bash execute the entire contents of ~/.bashrc via cron

Alex
  • 10,470
  • 8
  • 40
  • 62
  • 8
    Or set `$PS1` to some arbitrary value before `source`ing the `.bashrc` file; that way you don't have to change `.bashrc`. – Keith Thompson Mar 26 '13 at 00:41
  • 2
    That worked for me -- I have no idea why it was set that way, but it seems to have done the trick after hours of trying other stuff! – Avishai Jul 23 '13 at 00:49
  • this does not work for me on debian for some reason. I still don't get my `~/.bashrc` in cronjobs. – chovy Nov 08 '14 at 10:36
  • There is a reason this code exists in the file. The proper solution is to move code which should be executed by noninteractive shells to a different configuration file. A common arrangement is to put things you need in `cron` jobs etc in a separate file, and `.` (aka source; but the `source` command is only available in Bash, and cannot be used in `sh`) that file from your `.profile` and/or `.bash_profile` and/or `.zshrc` and/or `cron` jobs as required. – tripleee Jan 01 '22 at 12:23
13

Answer provided by @alex is correct but in Ubuntu 13.10 the code has been modified a little. There is no $PS1 variable but in lines 6-9 there is a code

case $- in 
   *i*) ;;       
   *) return;; 
esac

Just commenting out the line which returns works. i.e. the code below works

case $- in 
   *i*) ;;       
#   *) return;; 
esac
vdua
  • 1,281
  • 1
  • 14
  • 24
1

I just tried a file .env_setup_rc file with only one line export EDITOR=vim, surprisingly it's working.

So I guess there is something in .bashrc conflicting with the cron job bash command.

Peter Lee
  • 12,931
  • 11
  • 73
  • 100