Can I execute some commands when starting ssh session before getting to interactive mode?
Solution 1:
I'm self-answering, as I've finally discovered the secret. Neither -t
option for ssh
, nor -l
option for bash
will lead to login shell on their own - but in combination they work.
ssh [email protected] -t 'cd /some/where; FOO=BAR NUMBER=42 bash -l'
changes directory, sets environment variables, and then starts proper login shell (the only difference I've found so far is that /etc/motd
isn't displayed this way - it's normally ssh
's or login
's responsibility, not bash
's - other than that everything seems to work perfectly, and all environmental variables are identical).
These environment / directory changes happen after ssh, so they're not restricted by PermitUserEnvironment
and related settings (exactly as planned), but before .bashrc
/.profile
get executed. This has upsides and downsides - it is harder to just override something that gets set from bash init scripts like PS1
, but easier to pack exactly the right values into ssh
command lines, and have .profile
do all the heavy lifting.
And if really necessary, it's actually pretty easy to get bash to execute something after .profile
with command line like ssh [email protected] -t 'cd /mnt; echo ". ~/.bash_profile; PS1=\"\\h-\w \"" >~/xxx; bash --init-file ~/xxx'
- very ugly when put that way, but these alternative .profile
files can be prepared before.
(as far as I can tell bash
has a few candidate locations for .profile
script and will execute the first one found - . file
doesn't have such automatic fallbacks, so you'll need to check where's your normal profile
if you want to do that)
Solution 2:
Edit .bashrc and enclose your SSH-specific environment settings in:
if [ $SSH_TTY ]; then
...
fi
This would allow you to add settings specifically for SSH sessions. 'Course, if all you want is to set arbitrary environment variables right at the outset that vary by session, I don't know how you can make the machine guess them for you apart from typing them... no matter what, you'll need some testable condition to base the choice of settings on.
Solution 3:
From the ssh
man page:
Additionally, ssh reads ~/.ssh/environment, and adds lines of the format “VARNAME=value” to the environment if the file exists and users are allowed to change their environment. For more information, see the PermitUserEnvironment option in sshd_config(5).
which says:
PermitUserEnvironment
Specifies whether ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd(8). The default is “no”. Enabling environment processing may enable users to bypass access restrictions in some configurations using mechanisms such as LD_PRELOAD.
This facility could be used to conditionally execute statements in your remote ~/.bashrc
using the if
structure that Mickey suggested.