Skip to main content
quoting man page was literally copy-pasted, but I found it hard to read, so I thought to fix that with "normal" quote paragraph; edited tags
Source Link
Vlastimil Burián
  • 31.1k
  • 66
  • 208
  • 358

On my Arch install, /etc/bash.bashrc and /etc/skel/.bashrc contain these lines:

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

On Debian, /etc/bash.bashrc has:

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

And /etc/skel/.bashrc:

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

According to man bash, however, non-interactive shells don't even read these files:

   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  com‐
   mand 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.

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 commands were executed: if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi but the value of the PATH variable is not used to search for the filename.

If I understand correctly, the *.bashrc files will only be read if BASH_ENV is set to point to them. This is something that can't happen by chance and will only occur if someone has explicitly set the variable accordingly.

That seems to break the possibility of having scripts source a user's .bashrc automatically by setting BASH_ENV, something that could come in handy. Given that bash will never read these files when run non-interactively unless explicitly told to do so, why do the default *bashrc files disallow it?

On my Arch install, /etc/bash.bashrc and /etc/skel/.bashrc contain these lines:

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

On Debian, /etc/bash.bashrc has:

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

And /etc/skel/.bashrc:

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

According to man bash, however, non-interactive shells don't even read these files:

   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  com‐
   mand 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.

If I understand correctly, the *.bashrc files will only be read if BASH_ENV is set to point to them. This is something that can't happen by chance and will only occur if someone has explicitly set the variable accordingly.

That seems to break the possibility of having scripts source a user's .bashrc automatically by setting BASH_ENV, something that could come in handy. Given that bash will never read these files when run non-interactively unless explicitly told to do so, why do the default *bashrc files disallow it?

On my Arch install, /etc/bash.bashrc and /etc/skel/.bashrc contain these lines:

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

On Debian, /etc/bash.bashrc has:

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

And /etc/skel/.bashrc:

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

According to man bash, however, non-interactive shells don't even read these files:

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 commands were executed: if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi but the value of the PATH variable is not used to search for the filename.

If I understand correctly, the *.bashrc files will only be read if BASH_ENV is set to point to them. This is something that can't happen by chance and will only occur if someone has explicitly set the variable accordingly.

That seems to break the possibility of having scripts source a user's .bashrc automatically by setting BASH_ENV, something that could come in handy. Given that bash will never read these files when run non-interactively unless explicitly told to do so, why do the default *bashrc files disallow it?

Tweeted twitter.com/StackUnix/status/691767599420592130
Source Link
terdon
  • 252.2k
  • 69
  • 480
  • 718

Why does bashrc check whether the current shell is interactive?

On my Arch install, /etc/bash.bashrc and /etc/skel/.bashrc contain these lines:

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

On Debian, /etc/bash.bashrc has:

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

And /etc/skel/.bashrc:

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

According to man bash, however, non-interactive shells don't even read these files:

   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  com‐
   mand 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.

If I understand correctly, the *.bashrc files will only be read if BASH_ENV is set to point to them. This is something that can't happen by chance and will only occur if someone has explicitly set the variable accordingly.

That seems to break the possibility of having scripts source a user's .bashrc automatically by setting BASH_ENV, something that could come in handy. Given that bash will never read these files when run non-interactively unless explicitly told to do so, why do the default *bashrc files disallow it?