I have defined "SHELL" variable in /etc/crontab file:

[martin@martin ~]$ grep SHELL /etc/crontab 
[martin@martin ~]$ file /usr/local/bin/bash
/usr/local/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.0 (800107), stripped
[martin@martin ~]$ 

In addition, all my scripts in /etc/crontab file are started under user "martin". However /home/martin/.bash_profile(for login shell) and /home/martin/.bashrc(for non-logging shell) contain some variables which are ignored in case of cron job, but are used in case I log into machine over SSH or open new bash session. Why cron ignores those variables? Isn't cron simply executing "/usr/local/bin/bash my-script.sh" with permissions for user "martin"?


8 Answers 8


You can source the file you want at the top of the script or beginning of the job for the user that is executing the job. The "source" command is a built-in. You'd do the same thing if you made edits to those files to load the changes.

* * * * * source /home/user/.bash_profile; <command>


source /home/user/.bash_profile

  • 3
    Note that "source" might not work if cron is not using the bash shell. I've added an answer that can handle the case when the shell is sh.
    – Jonathan
    Commented May 3, 2017 at 7:40
  • ^ source not found error fix Commented Feb 1, 2018 at 1:33
  • #!/bin/bash source /home/ubuntu/.bashrc it is not working for me. .bashrc won't work ? Commented Jan 22, 2020 at 12:13
  • if source does not work, then try .. Example; . /home/user/.bash_profile Commented Oct 12, 2020 at 17:10

Because it's not an interactive shell. The same happens when you open some terminals.

Have a look at this question: What is the .bashrc file? | Super User

And also at this one:

What's the difference between .bashrc, .bash_profile, and .environment? | Stack Overflow

Different scripts fire depending on if the connection is a login shell (or not), an interactive shell (or not), or both.

If you want to make bashrc you'll need to make this change:

When Bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi 

but the value of the PATH variable is not used to search for the file name.

As noted above, if a non-interactive shell is invoked with the --login option, Bash attempts to read and execute commands from the login shell startup files.

Source: Bash Startup Files | Bash Reference Manual | gnu.org

  • 1
    So if we set BASH_ENV inside Cron, cron bash scripts will source that because cron is non-interactive and non-login. Commented Dec 11, 2015 at 7:19

You may not be able to run source if the sh shell is being used. This can be changed by adding the following line in your crontab:

* * * * * source "/root/.bashrc"; <command>

You can also specify the environment:

* * * * * <command>

or you can use your local /home/user/.bashrc if it is a user cron job (e.g. crontab -e).

Note that .bash_profile can replace .bashrc, if it exists.

Credit: How to change cron shell (sh to bash)?

  • this works well also for Acquia Cloud Scheduled jobs, which are basically cron jobs. You can do the same, like: SHELL=/bin/bash && source /home/YOUR_USER_NAME/.bash_profile && sh .... Commented Jan 22, 2019 at 17:58
  • Does SHELL=/bin/bash apply only to the cron that immediately follows, to all those that follow, or to the whole /etc/crontab?
    – matteo
    Commented Jun 19, 2021 at 18:27

You could invoke bash with the -l option, like this:

* * * * * /bin/bash -l /path/to/script arg1 arg2

The -l option makes bash a login shell. Thus, it will read the user's .bash_profile. It won't read the user's .bashrc unless it is explicitly sourced by .bash_profile. This is because non-interactive shells don't automatically read .bashrc. But you shouldn't need .bashrc for a cron job. .bashrc is for setting things useful to interactive shells, like setting PS1 and creating aliases.


If bash is on the PATH, there's no need to specify an absolute path to it:

* * * * * bash -l /path/to/script arg1 arg2

An optimization would be to replace the current shell by using exec:

* * * * * exec bash -l /path/to/script arg1 arg2

See Why do some Linux shell scripts use exec to run commands? for discussion of the use of exec.


Something else that might interfere with the sourcing of your .bashrc from a cronjob is any checks that this file does in order to detect interactive shells.

For example, on Ubuntu 18.04, the default .bashrc for a user starts with this:

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;

and so sourcing it won't do anything useful since it will exit immediately.

  • 1
    This turned out to be critical for me. I moved the relevant portion of my .bashrc into .bash_profile, updated the file path in my cronjob, and suddenly the same cron command worked.
    – Dawson B
    Commented Nov 4, 2020 at 5:28
  • bash -i starts an interactive shell. bash -lic 'some bash code' is a useful recipe. Commented Feb 14, 2021 at 13:33

I had the same issue when executing a node application from cron which uses NVM , In order to make bash shell to read the .bashrc file from cron just envoke the bash command with interactive shell option `-l.

eg: * * * * * /bin/bash -lc '/home/user/myapp.sh restart'

If that doesn't work try setting path variable in crontab

41 7 * * * /bin/bash -lc "PATH=$PATH:/home/user/.nvm/versions/node/v8.10.0/bin && /home/user/script.sh restart "

bash acts differently whether it is a shell or a normal programming language (like perl or python).

By design, the settings in ~/.bash_profile, ~/.bashrc, etc. are for users to set things when bash plays the role of a shell (login shell, interractive shell). Think about environment you have in a xterm (interactive shell) or in ssh sessions (login shell) or in consoles (login shell).

In other hand, bash is also a powerful progamming language –think about many scripts for managing services in systemd– which requires a different style of working. For example, when a developer is writing a system script or a bash program, he/she will not like to source the user's ~/.bash_profile automatically. It is a normal program, not a shell. A normal program (including bash programs) would naturally inherit settings from the current working evironement (shell), but not set them.

If we write a program for cron in bash –it just happens to be written in bash; in fact, we can write it in python or perl or any other progamming language– then we can have an option to sources bash's ~/.bash_profile (read: setting of user's shell, which just happens to be the same language of your programming language):

[ -f /home/user/.bash_profile ] && . /home/user/.bash_profile

However, what if that particular user do not use bash as his/her shell? He/she may use zsh, ksh, fish, etc. So, that practice would not really work when writing program for public use.

So, you can source ~/.bash_profile if you think that will work. But, here, it is not about whether we are able to source a file, it is about how things should works in the system: the design concept. In short: we should view bash as something having 2 roles: shell and progamming language. Then everything will be much easier to understand.


My way to deal with it was this:

1) Putting my variables in (the end of) ~/.profile:


2) Creating a Bash script for my (daily) cron tasks (~/cronDaily.sh) containing my commands plus repetitive sourcing of ~/.profle:

source ~/.profile
command ${myVarInDotProfile}/

3) scheduling my script's execution from crontab, to run daily:

0 0 * * * bash ~/cronDaily.sh

My variable wasn't ignored and the commands ran successfully.

Some may say such intense sourcing of ~/.profile is problematic. In my particular case I don't see why it is a problem but I would advice to consider creating a dedicated file for that.

In general, there might be a better way to this but that's what worked for me after a lot of pain and it explains the principle that as of Bash 4.3.46, you cannot source a file from crontab.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .