December 24, 2010

Day 24 - Terminal Multiplexers

Written by Jon Heise

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:

Note: screen and tmux are generally controlled by multiple keystrokes. In the examples below, C-a means pressing "control + a" keys. A sequence 'C-a d' means press "control + a", release, then press 'd'. This syntax is common in screen and tmux documentation.

goal screen tmux
run irssi screen -S irc irssi tmux new irssi
detach C-a d C-b d
attach again screen -r irc tmux attach

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:

tmux session list

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

tmux splits example

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:

set-option -g prefix C-a  # make the command key C-a
unbind-key C-b            # unbind the old command key
bind-key a send-prefix    # 'C-a a' sends literal 'C-a'

Why would you do this? If you've used screen for years, and want some of your muscle memory to function in tmux, doing the above is a good start.

Cheat sheet

In closing, here is a recap of commands in convenient cheat sheet form:

action screen tmux
new named session screen -S foobar tmux new -s foobar
detach session `C-a d` `C-b d`
reattach session screen -dr foobar tmux a -t foobar
new terminal `C-a c` `C-b c`
next terminal `C-a a` or `C-a n` `C-b n`
lock terminal `C-a x` lock (from command prompt)
large clock not supported `C-b t`
not as good smaller clock `C-a t` not supported
split screen horizontal `C-a S` `C-b “`
split screen vertical `C-a |` `C-b %`
change to other portion of a split `C-a tab` `C-b arrowkey` (up or down)
send prefix `C-a a` `C-b C-b` (if

Happy tmux'ing and screen'ing!

Further reading:

3 comments:

  1. I have some fun screen hacks. I'll show two:

    First, all my xterms run like this:

    xterm -e screen -RR

    'screen -RR' re-attaches the first detached screen; if none are found, it creates a new session. This lets me kill xterms (by accident, whatever) and the next xterm will resume that screen session.

    This can be applied to gnome-terminal or other terminals.

    Second, I have a few screen scripts to aid in finding screen sessions.

    http://code.google.com/p/semicomplete/source/browse/tools/screen-find.sh

    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.

    ReplyDelete
  2. Wow, nice post,there are many person searching about that now they will find enough resources by your post.Thank you for sharing to us.Please one more post about that..

    ReplyDelete
  3. Best thing about tmux is the easy scriptability and hacking src. GNU screen is more less change resistant, i.e., see vertical split patch.

    Has anyeone else, however, noticed that tmux seems to have a memory leak with many tty's open over several weeks?

    ReplyDelete