How can I run a script immediately after connecting via SSH?

I started to ask this question but answered it while I had it open. I’m going to post this question, follow it up with my solution and leave it open to other potential solutions.

<backstory>

I’m a tmux and vim user. I like remote vim work as I don’t have to worry about Ubuntu development machines kirking out when a flash movie gives me a kernel panic. Running tmux means that open files are waiting for me after I reboot and I can carry on from where I left off. I’ve had problems with vim running in a tmux session when I connect like so:

ssh example.com -t 'tmux attach'

UTF-8 issues crop up that don’t crop up when shelling in normally and just attaching to a tmux session manually.

</backstory>

So I want a reusable method of starting something on ssh login, that doesn’t affect any of the other things I have configured in my .zshrc (or your .bashrc if you still use bash) that may be required for my development environment, that doesn’t appear when I’m occasionally working locally on the very said machine.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

Method 2

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.

Method 3

Myself, I add this to my .bash_profile files:

if [ -z "$STY" ]; then
    reattach() { exec screen -A -D -RR ${1:+"<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a387e3">[email protected]</a>"} ; }
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.

Method 4

You might consider running

ssh remotehost -t screen -DR

and run your terminal session there. You can then detach (^A^D) and reattach later (from a different client as well). It will make the problem with non-interactive initialization go away as screen keeps full interactive terminal sessions (optionally logon shells as well, man screen(1) or ^A?)

Method 5

To speak to the UTF-8 issues specifically, if you add

SendEnv LANG

And $LANG is set to something like en_US.UTF-8 on the local end and your sshd on the remote end permits the SendEnv directive (with AcceptEnv in sshd_config), the tmux on the other end should honor it. I had this problem for a while and it was difficult to troubleshoot.

Method 6

If you want it to run every time you connect, you could simply add tmux attach to the bottom of your ~/.profile on the remote machine.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x