Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
add comment

6 Answers 6

up vote 10 down vote accepted

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.

share|improve this answer
    
The reason I'm not using ssh example.com -t 'tmux attach' isn't because it has problems loading my environment but because I've had issues with UTF-8 character display; this issue doesn't exist when connecting in the conventional manner. This is why this question is about running scripts immediately after connecting over SSH. –  connrs Mar 23 '11 at 9:17
    
I love your solution though. Elegant –  connrs Mar 23 '11 at 9:49
    
@connrs: Do you have issues with UTF-8 even when you run your .profile? I assumed the issue was due to incorrectly set locales on the target machine, which your /etc/profile or .profile fixed. The locale issue is probably fixable with more information. –  Gilles Mar 23 '11 at 19:33
    
I wanted to get back to the office to test this. You are totally correct, sourcing the /etc/profile does trigger proper behaviour. You've now actually solved the problem that motivated me to ask this more generic question –  connrs Mar 25 '11 at 9:13
add comment

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.

share|improve this answer
2  
Use of PermitUserEnvironment will not be possible in some environments due to the potential security implications. SSH sets the $SSH_CONNECTION variable, which can be used in place of your $SSH_LOGIN in your .zlogin, obviating the need to use ~/.ssh/environment. Something like if [[ "$SSH_CONNECTION" != "" ]] should do it. –  Eli Heady Mar 22 '11 at 12:42
add comment

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.

share|improve this answer
add comment

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?)

share|improve this answer
    
As mentioned in my question, I'm using tmux rather than GNU screen to manage my sessions. And when loaded with -t 'tmux attach' I have issues with vim that aren't present normally. This is why the real question is about running scripts on ssh connect rather than screen/session management. Apologies for not being clearer in my question –  connrs Mar 23 '11 at 9:44
    
So sorry, you mentioned tmux but it didn't mean anything to me. Thanks for mentioning a new tool though! –  sehe Mar 23 '11 at 9:49
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.