Bashrc Non-Interactive – Why No Such Non-Interactive Version of Bashrc

bashrcdaemonenvironment-variableshistoryinteractive

From what I understanding, a daemon is a background process, but daemon requires unique config file to set the environment variable.

E.g. Hadoop daemon require hadoop-env.sh to set environment variable JAVA_HOME, you can't simply get the variable from ~/.bashrc.

The reason is because of daemon as a background process means it's non-interactive, while ~/.bashrc is means to used only from interactive session, to prevent alias cp='cp -i' case.

And the latest ~/.bashrc has the safe guard on top of the file do not allow non-interactive caller, i.e. without -i option will return early:

# ~/.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;;
esac

It make me wonder why bashrc don't divide the config files to 3 groups, such as:

  • ~/.bashrc_interactive

  • ~/.bashrc_non_interactive

  • ~/.bashrc_global #(both interactive and non interactive)

So user can simply set JAVA_HOME in ~/.bashrc_non_interactive or ~/.bashrc_global, and no need to add this environment variable in each daemon file, over and over again.

Is there any reason or restriction of why bashrc not support non-interactive on that way or any other way ? OR am I misunderstanding some concepts ?

Best Answer

You already have the opportunity to set BASH_ENV to the pathname of a file that non-interactive shell script parse before running.

This allows you to do, in a crontab for example

@hourly BASH_ENV="$HOME/.bashrc_non_interactive" "$HOME/bin/mybashscript"

or even

BASH_ENV="$HOME/.bashrc_non_interactive"

@hourly "$HOME/bin/mybashscript"
@daily  "$HOME/bin/myotherbashscript"

$BASH_ENV is usually empty, but there's nothing stopping you from setting it globally on your server, pointing it to a file under /etc that does

if [ -f "$HOME/.bashrc_non_interactive" ]; then
    . "$HOME/.bashrc_non_interactive"
fi

However, if a script needs specific variables set, such as JAVA_HOME etc., then it may be a better idea to set BASH_ENV explicitly on a script by script basis, or to explicitly source the relevant file from within the script itself, or to just set the variables in the script. Collecting all the things any non-interactive shell may want to use in a single file may slow down scripts and will potentially also pollute the environment of scripts with things they do not need.