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.


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.


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.


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

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.

  • 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 'SO- stop being evil' 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

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";;

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.

  • 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

Myself, I add this to my .bash_profile files:

if [ -z "$STY" ]; then
    reattach() { exec screen -A -D -RR ${1:+"$@"} ; }
if [ -t 0 ]; then
    screen -wipe
    echo 'starting screen... (type Ctrl-C to abort)'
    sleep 5 && reattach

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.

  • Great! I managed to f* this up by putting in bashrc instead, and then in each new screen window - when changing to .profile it worked fine. – Hugo Nov 20 '18 at 12:34

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

  • 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

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.


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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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