December 24, 2010

In the grand world of the command line and in dealing with servers, persistence is
key. To that end, there are ways to run stuff that lives beyond your current
ssh session, this article will focus on screen and tmux. These tools help you
run shell sessions that persist across logins (among other awesome
capabilities).

GNU Screen is by far the older of the two being first released in 1987. Tmux
was released much more recently in 2007.

Similarities

First off, let's talk similarities. They both have the core functionality of
being able to “detach” a session from active usage by a user. Let's say a user
wants to run irssi (an irc client) and detach it - the workflow would be as
follows:

FYI: The default screen command key is C-a, while the default tmux command
key is C-b. Most things you do in screen and tmux, by default, will always start
by pressing the command key.

The above examples create a screen session called 'irc' and an unnamed tmux
session. Both tmux and screen also support multiple terminals in one session,
that is, you can run multiple commands in separate windows in the same screen
or tmux session.

goal

screen

tmux

create new window

C-a c

C-b c

go to previous window

C-a p

C-b p

Using multiple windows in tmux is a bit easier, by default, as there is an
omnipresent status bar at the bottom of the terminal showing open windows.

You can get a list of all known sessions:

screen -ls

tmux ls

That's the basics of each - first: creating, attaching, and detaching sessions,
and second: creating new windows in a session.

Differences

Having listed features that they both share, it is time to discuss features that
one posses that the other does not.

Screen has special features like serial port support and multiuser access.
Screen can directly open serial connections from other machines, network gear,
or anything that wants to spew data forward on a serial terminal. This feature
can be handy for sysadmins with macbooks that need to configure some network
gear as there is no good mac specific terminal emulator software. Connection to
a serial port is simple:

screen /dev/ttyN

Additionally, you can share your screen sessions with other users on the system
with screen's "multiuser" feature. This allow you to share terminals with
remote coworkers to do pair debugging or shadowing without having to use
a user shared account. See the screen documentation for the following commands:
multiuser and acladd.

Tmux's main feature is the client/server model it uses. Earlier it was
mentioned that not being able to specify a specific instance of tmux was less
of a nuisance, this is due to the fact that tmux runs in a client server model.
As long as there is a session of tmux running (even in the background), the
tmux server will exist to manage it. Since there is a central server dealing
with each tmux client and session, it is far simpler for the client that the
user has launched to be aware of these. If you have multiple tmux sessions
running (via tmux new), you can ask any tmux session to list them by typing
'C-b s', the result looks something like this:

From the above session list, you can switch to any other open session.

Until recently, tmux (vs screen) was the only one supporting both vertical and
horizontal splits. You can create horizontal splits with C-b " and C-b %
for vertical splits. In screen, horizontals are made with C-a S and verticals
made with C-a | (pipe).

Tricks

You can nest screens within screens, or tmux within tmux. This is most common
when running tmux or screen, sshing to another server, and running screen/tmux
from there.

goal

screen

tmux

start up

screen -S main

tmux new -s main

ssh somewhere

ssh ...

ssh ...

create a new session on remote host

screen -S foo

tmux new -s foo

The main problem with nesting is knowing how to talk to the nested session. To
detach from the 2nd screen session (nested) you'll have to send 'C-a a' which
will send a litteral C-a from the first screen to the running program, which is
another screen session. Detaching from the nested screen, then, would be 'C-a a
d'

This is similar with tmux, though your tmux may not be configured similarly.
You may have to add this to your ~/.tmux.conf:

bind-key C-b send prefix

Now pressing 'C-b C-b d' will detach from the nested tmux

The above only applies if you nest screen-in-screen and tmux-in-tmux. If you
have screen-in-tmux, you would just press the normal C-a to talk to screen. Same
with tmux.

Making them similar again

Screen's defaults don't usually include a status bar, but you can make one similar to tmux by adding this to your ~/.screenrc:

hardstatus alwayslastline "%w"

You can also tune tmux to behave more like screen by changing the command key. In your ~/.tmux.conf:

The above one will grep the viewable text on each screen session and, if detached, attach to it, and if attached, 'blink' the screen so you can see it. This is useful if you've got a pile of screen sessions and you don't know what is what. The 'tools' directory in the url above also has a few other screen-* named scripts that serve other purposes.