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
.