Starting tmux Sessions via SSH

tmux is a terminal multiplexer which allows a user to switch between several terminal sessions within the same terminal window. In addition, tmux allows one to detatch and reattach sessions while the programs within the session continue to run unimpeded. This latter feature is great when remotely accessing a system and running long duration programs, such as compiling a large program from source. With tmux one can start a build, detach the session, log off and then log back in at some later time to see the build status.

Unfortunately, as luck would have it, so many times I have started a remote command and then wished I had launched tmux so I could reconnect later. What I wanted was an easy way to automatically launch tmux when I log into a particular host.

Configuring tmux to start via ssh

In order to launch tmux via ssh you need to provide the following in your ~/.ssh/config file:

Host myhost
    RequestTTY yes
    RemoteCommand tmux new-session -A -s mysession

When one runs the command ssh myhost, this configuration will launch tmux on the remote system and attempt to attach (-A) to an existing session named mysession. If no such session exists, it will create a new session. It is important that the option RequestTTY is enabled, otherwise tmux will fail with the error, “open terminal failed: not at terminal”.

However this simple configuration leaves a little to be desired. What if you want to sometimes connect to the host without launching tmux? Or what if you already have a session with tmux running and you want another login with a different tmux session?

An Improved Solution

The following is an interesting hack that allows one to choose the session name from the ssh command itself.

Host myhost-*
    Hostname myhost
    RequestTTY yes
    RemoteCommand tmux new-session -A -s ${%n}

With this configuration, I can run the command ssh myhost-session-1 and it will ssh to the host myhost and attach or create the session session-1. If I wish to login with a different session, I just need to change the text after the first hyphen – for instance, ssh myhost-session-2.

Additionally, if I run ssh myhost without any suffix, it will log into myhost without invoking tmux at all.

How Does This Work?

OpenSSH has a number of predefined tokens that can be used to substitute variable text into the RemoteCommand or other keyword values. In this case, %n returns the remote hostname as given on the command line. You can see more possible tokens on the ssh_config (5) man page.

Another feature of OpenSSH configuration language is that one can reference environment variables by enclosing the variable name in ${} (for instance , ${HOME}), much like one would in Bash or other shell languages. Bash has the additional syntax ${variable-default} which will return the value “default” if ${variable} is not set (see the always useful Advanced Bash Scripting Guide for details). It turns out OpenSSH supports this same syntax.

Putting these together, when we run the command, ssh myhost-session-1, the %n token will evaluate to “myhost-session-1”. As we enclose this token within ${ } it becomes ${myhost-session-1} which is evaluated to return the value of ${myhost} if defined, otherwise return the default value, “session-1”. As long as there is no environment variable (on the local system) named myhost, the text after the first hyphen will be passed as an argument to the -s flag of tmux.