Bash – ~/.bashrc Not Sourced on SSH Command

bashbashrcdebianlinuxUbuntu

At the end of .bashrc I added:

touch /tmp/bash_noninteractive_test

Run:

/usr/bin/ssh -v -C root@example.com 'ls'

On the host (logged in interactively before):

% ls -l /tmp/bash_noninteractive_test
ls: cannot access /tmp/bash_noninteractive_test: No such file or directory

I thought ~./bashrc is ALWAYS sourced in non-interactive shells, like over SSH? How do I fix that?

Systems affected:


% lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty


% lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.11 (jessie)
Release: 8.11
Codename: jessie

Best Answer

From the INVOCATION chapter of man bash:

When an interactive shell that is not a login shell is started, bash reads and executes commands from /etc/bash.bashrc and ~/.bashrc, if these files exist. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of /etc/bash.bashrc and ~/.bashrc.

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 filename.

So it appears that ~/.bashrc is never sourced on non-interactive shells, unless BASH_ENV points to it.

Depending on what you wish to actually achieve, you might consider enabling PermitUserRC and/or PermitUserEnvironment in /etc/ssh/sshd_config on your remote host, and then writing the desired environment variables in ~/.ssh/environment and/or the desired commands in ~/.ssh/rc.

NOTE: if you plan to use SSH X11 forwarding together with ~/.ssh/rc, you must include a snippet of code to explicitly feed the X11 session to the xauth -q - command; see the example in the SSHRC chapter of sshd(8) man page.