How can I run a script immediately after connecting via SSH?
When you run ssh example.com
, the ssh daemon starts a login shell for you, and the login shell reads your ~/.profile
(or ~/.bash_profile
or ~/.zprofile
or ~/.login
depending on your login shell). When you specify a command to run remotely (with or without -t
), the ssh daemon starts an ordinary shell, so your .profile
is not read. Remedy:
ssh example.com -t '. /etc/profile; . ~/.profile; tmux attach'
Most ssh daemons are configured to refuse transmitting environment variables except for LC_*
. If the ssh daemon on example.com
allows it, you can abuse a custom LC_*
variable to start tmux automatically — put this in your ~/.profile
:
if [ -n "$LC_tmux_session" ] && tmux has -t "$LC_tmux_session"; then
exec tmux attach -t "$LC_tmux_session"
elif [ -n "${LC_tmux_session+1}" ] && tmux has; then
exec tmux attach
fi
then log in with LC_tmux_session= ssh example.com
or LC_tmux_session=session_name ssh example.com
.
This answer has more information about passing environment variables over ssh.
I previously advised setting PermitUserEnvironment yes
and adding an environment variable in your ~/.ssh/environment
until Eli Heady chipped in with a better suggestion in the comments below.
Open your .zlogin
(bash: .bash_profile
etc.) and put the following:
if [[ "$SSH_CONNECTION" != "" && "$MY_SSH_CONNECTION" != "yes" ]]; then
while true; do
echo -n "Do you want to attach to a tmux session? [y/n]"
read yn
case $yn in
[Yy]* ) MY_SSH_CONNECTION="yes" tmux attach; break;;
[Nn]* ) break;;
* ) echo "Please answer y/n";;
esac
done
fi
Inspiration taken from: How do I prompt for input in a Linux shell script?
Note that I've used the .zlogin
file but you could use your .zshrc
file but I like to keep my dotfiles tidy and it separates it so I can use it on other machines.
Replace the question with something appropriate for yourself and replace MY_SSH_CONNECTION="yes" tmux attach
with whatever you wish to run at that point.
Note how the script sets MY_SSH_CONNECTION="yes"
before tmux attach
to pass it through to tmux as it also will be opening a shell that will access the very same script above and will prevent any recursion.
Myself, I add this to my .bash_profile files:
if [ -z "$STY" ]; then
reattach() { exec screen -A -D -RR ${1:+"$@"} ; }
fi
if [ -t 0 ]; then
screen -wipe
echo 'starting screen... (type Ctrl-C to abort)'
sleep 5 && reattach
fi
This gives me some time to abort reattaching to or creating a screen session. It won't work on 'ssh system command' formats (which does not call ~/.*profile). A shell function is set up to reattach if I abort.