In my reading of the bash manpage, .bashrc should only be executed when the shell is run interactively. The manpage defines interactive as:
An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state.
Yet, executing a command with ssh also causes .bashrc to be run, contrary to what I would expect, given that the command is not run interactively. So, this behavior seems like a bug, but it also seems pervasive on all the versions of Red Hat and bash that I've tried. Can someone explain why this behavior is correct?
One additional point: even though .bashrc is run, $-
and $PS
are set as if the shell is non-interactive (as I would expect).
$ grep USER /etc/passwd
USER:x:UID:GID:UNAME:/home/USER:/bin/bash
$ cat ~/.bashrc
echo bashrc:$-,$PS1
$ bash -c 'echo $-'
hBc
$ ssh localhost 'echo $-' </dev/null 2>/dev/null
USER@localhost's password:
bashrc:hBc,
hBc
$ ssh localhost 'ps -ef | grep $$' </dev/null 2>/dev/null
USER@localhost's password:
bashrc:hBc,
USER 28296 28295 0 10:04 ? 00:00:00 bash -c ps -ef | grep $$
USER 28297 28296 0 10:04 ? 00:00:00 ps -ef
USER 28298 28296 0 10:04 ? 00:00:00 grep 28296
I am currently working around this by testing [[ $- = *i* ]]
in .bashrc, but it seems as if I shouldn't have to do that.
One example server, containing no other files in my home directory than .bashrc (and .ssh) has this configuration:
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.7 (Tikanga)
$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.
Versions of bash that I've tried this on: 3.00.15, 3.1.17, 3.2.25, 4.1.2 (the latter on Red Hat 6.3).