Linux – Which bash rc files are run on non-interactive/non-login shells

bashbash-scriptingbashrccronlinux

My Understanding

  • there are no rc files called for non-interactive/non-login shells; for example, those run by cron
    (I don't know this for certain and would lean on the community's expertise)

  • non-interactive shells require the BASH_ENV environment variable to be set, which enables to set it to a particular rc file (e.g., BASH_ENV=$HOME/.bash_profile)

The Hope

I'm not certain about the plethora of rc files available, so am curious if there is ones that I'm not familiar with. Hoping to find an rc file that meets the following conditions:

  • called regardless of interaction/login mode so global shell environment variables can be set in one place
  • performs more like csh/tcsh

Best Answer

The answer to your specific question is that often only /etc/bash.bashrc (or /etc/bashrc) is loaded.

There seem to be a couple of ways to address this, most are workarounds unfortunately. In no particular order of preference:

Fake a login

Logins run /etc/profile and often you can place your custom scripts in /etc/profile.d/*.sh

Wrap it in a bash login

Sometimes it is easiest to trigger a login, i.e.

echo "do whatever $PATH $BASH $PS1 $0"

becomes

bash -lc 'echo "do whatever $PATH $BASH $PS1 $0"'

Manually load the profile

Do what logins do, manually load the profile

source /etc/profile;echo "do whatever $PATH $BASH $PS1 $0"

Edit global environment variables

For simple variables you can add to /etc/environment see Ubuntu System-wide_environment_variables but variable expansion does not work

THING_HOME="/opt/thing"
PATH="$PATH:/opt/thing" # this will NOT work

For PATH you could append to it e.g. sudo sed -i 's#PATH=\"[^\"]*#&:/opt/thing#' /etc/environment

Edit all bash shells

You can add to /etc/bash.bashrc (or /etc/bashrc) however this normally exits early if non-interactive so you need to hack your additions on before:

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

Do none of these

  • Consider symlinks if you are trying to add something to the PATH
  • Consider making your programs/scripts modify their own environment
  • Systemd has EnvironmentFile and Environment e.g. systemctl edit --full cron.service

I am interested in hearing if anyone else has better workarounds!

Related Question