I would like run remote ssh commands and have them always load server-side startup files by default. I am looking for a solution that does not require:
- configuration by root
- adding extra boiler plate to the command each time
- duplicating environment variables across multiple files
I am not looking to transport local environment variables to the remote shell. I want to run a remote command using the vanilla ssh <host> <command>
syntax and have it run using the same environment a remote login session would get.
Background
The below assumes bash
is being used for simplicity
By default, remote ssh commands start a non-interactive, non-login shell. Quoting the man page:
If command is specified, it is executed on the remote host instead of a login shell.
You can see this more explicitly on the shell by running:
# the lack of 'i' indicates non-interactive
$ ssh localhost 'echo $-'
hBc
$ ssh localhost 'shopt login_shell'
login_shell off
But what if your remote command needs certain environment variables set? Being a non-interactive, non-login shell means neither .bash_profile
nor .bashrc
will be sourced.
This is problematic, for example, if you're using tools like perlbrew or virtualenv and want to use your custom interpreter in the remote command:
$ which perl
/home/calid/perl5/perlbrew/perls/perl-5.20.1/bin/perl
$ ssh localhost 'which perl'
/usr/bin/perl
Solutions that do not satisfy the requirements above
Explicitly invoke a login shell in the remote command
$ ssh localhost 'bash --login -c "which perl"'
Requires extra boiler plate each time
Explicitly source your profile before the command
$ ssh localhost 'source ~/.bash_profile && which perl'
Requires extra boiler plate each time
Set environment variables in ~/.ssh/environment
Requires root to enable this functionality on the server
Duplicates environment variables already set in server startup files
Set ENV
and BASH_ENV
Does not work: .bash_profile
and .bashrc
aren't sourced
Setting in ~/.ssh/environment
works, but requires root access to enable
Preface the command with the environment variables you need
Requires extra boiler plate each time (potentially a lot)
Duplicates environment variables already set in server startup files
.bashrc
if your login shell is bash, or acommand=
directive in.ssh/authorized_keys
. – Gilles 'SO- stop being evil' Mar 28 '15 at 00:36.bashrc
trick is hit or miss and may require explicitly compiling bash withSSH_SOURCE_BASHRC
set, which makes it even less palatable. (For example it works on my work RHEL6 but not my home Arch Linux). Unfortunate the bash man page doesn't mention this caveat. – Dylan Cali Mar 28 '15 at 07:12.bashrc
over SSH was optional, I'd only encountered bash binaries that have it, thanks. Thecommand=
solution is as good as it gets without root's intervention, and having it per-key is actually a good thing on a shared account since it lets each person have their own initialization file. What's icky about it? – Gilles 'SO- stop being evil' Mar 28 '15 at 14:53