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
.bashrcif your login shell is bash, or acommand=directive in.ssh/authorized_keys. – Gilles 'SO- stop being evil' Mar 28 '15 at 00:36.bashrctrick is hit or miss and may require explicitly compiling bash withSSH_SOURCE_BASHRCset, 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.bashrcover 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