Screen and tmux

Screen and tmux are two similar programs that are terminal multiplexers. This means that you can do several things in one terminal. It's the kind of thing that once you find it, you wonder how you managed without it.

We'll start with screen, as it's older and (at time of writing), much more common. Open your favorite terminal

Start by typing
screen

Suppose you have a huge directory that you want to copy somewhere, but don't really feel like watching it. So, in this screen session
cp -r large_directory somewhere_else

The default prefix for a screen command is Control+a, which we'll abbreviate as C-a. Now, you can detach this screen.
C+a d

You're back to your original terminal, where you can do whatever you want. This is especially useful with remote log in sessions.

Now, if you want to see how the copying is going, you can reattach the screen session with
screen -r

as in reattach.

This becomes more useful with remote login sessions. If logging into RemoteServer1, you can open a screen session on the remote machine, run your commands, then detach the screen. You can now log out of RemoteServer1. When you log back into RemoteServer1, you can type screen -r and have your session back.

If your connection isn't reliable, it doesn't matter, Once the screen is detached, even if you completely disconnect from the remote server, the screen session on that server is still intact.

Sometimes, you may need to do things on RemoteServer1. Perhaps you want to run that large copying job and also do some compiling. You can open up multiple screen sessions, and to help you remember which is which, give them titles.

So, I log into the remote server and open a screen session.
screen -S copy

I open that session and begin my copying job. I detach it, and open a second session.
screen -S compile

I detach that one, log out of the remote server, and go about my business. A bit later, I log back into the remote server and check what screens I have running.
screen -ls

I will get something like
There are screens on
15033.copy   (Detached)
15037.compile (Detached)

The number is the PID (Process ID) number. Afterwards is the title I gave the session. Now, I want to check the compile.
screen -r compile

This brings me back to the session that I'm using to compile. If one is administrating several servers remotely, especially if a connection is not reliable, it becomes invaluable.

Another useful feature of screen is its ability to split a terminal into multiple sections. If in a terminal session to a remote server, we might want to compare two files. While logged into the remote session, open screen. Then, to split the screen vertically, type the following sequence. (Remember C-a is Control+a)
C-a
Shift+S

This will now give you a split window (the S is for split), with the cursor in the top window. You can run a command here. To get to the second window, once again hit C-a, then tab. You will see the cursor in the second window, but won't yet have a command prompt. Once again, hit C-a then c as in command. To move back and forth between the windows, use C-a tab. You can split the window multiple times to have as many as you wish.

Sometimes, accidental keystrokes will change it so that both windows are showing the same thing. The way to fix that is to hit C-a p (as in previous) or C-a n (as in next). This will bring the second window back to where it should be.

I've never figured out a good way to kill just one of the windows (or regions, as screen calls it when you split a window), in a screen session. (This is one reason I've switched to tmux). If one types exit in the bottom region, one just goes back to a cursor, with no command prompt. The man page indicates that C-a X should kill it, If you type exit in the top window, it terminates the entire screen session. The secondary windows can be difficult to close.

It seems to work on occasion, but sometimes, depending upon what machine I'm on, it seems to not recognize the fact that it's X rather than x or give me some other issues. This is a minor thing, and one that I suspect I could solve if I put minimal effort into it, but, regardless, it's one thing that tmux, at least for me, does better.

Yet another useful function of screen, whether on local or remote machine, is to use one terminal, whether console or xterm, to run several terminal sessions. Going back to our earlier example of running a copying and compiling session on a remote machine, it can be done with one screen session. On the remote machine open a screen session and start your copying job. Now hit C-a and c as in command. You'll have a new window, which is still part of the same screen session. Start your compiling job. Detach the screen with C-a d and go back to what you were doing.

When you log in again, run screen -r to reattach. It will return you to the window you were using last. That is, if you deattached while viewing the compiling session, it should return you to that one. To view the copying session, hit C-a p, as in previous, and it will take you back to the copying session. In this case, as opposed to split windows, typing exit will close the current window. That is, if you're done with the copy, but the compiling is still going on, you can type exit in the window with the copying session, and you will be returned to the screen session's second window, the compiling window.

This can be useful on a local machine as well. I use fluxbox or openbox. If I have 6 xterms doing various things, I might have to tab between them, and have them scattered all over the display. If I use screen, I can open only one xterm, then use C-a c to open several terminals that I don't need to view at once, using only one xterm session.

Tmux

Tmux is quite similar to screen. It's much newer, and is released with a BSD, rather than GPL, license. It is supposedly less resource intensive, though I haven't really noticed. I'm not a programmer, so can't judge this, but I've also seen it said that its code is cleaner.

Some people find its documentation to be clearer than screen's. This may turn into one of those vi vs. emacs wars, but at present, tmux is still relatively unknown. For example, on both Fedora and CentOS forums, at time of writing, I've only seen one thread on tmux, in both cases, one started by myself to ask if anyone used it. On some of the less GUI centric distro forums, such as ArchLinux, this isn't the case. Tmux has also become part of the OpenBSD base install. Most Linux distributions have a package for it.

An earlier version of this page mentioned that the rpmforge rpm for tmux wasn't working. That has since been fixed, and CentOS users can easily install tmux from rpmforge.

There's an excellent screen/tmux cheat sheet by Dayid Alan, which can be found here. It's very useful for those wanting to try something new.

Tmux uses Control+b rather than Control+a by default. Many people like to change this. Create a .tmux.conf in your home directory. (Note the period in front of the name.) To change the key binding from C-b to C-a, put the following in the file
unbind C-b
set -g prefix C-a

The syntax is unbind <default-key-binding> and set -g (as in global), <preferred-key-binding> (Note that the cheat sheet mentioned above, uses the default key bindings.)

There's a simple example .tmux.conf file in this article about migrating from screen to tmux.

However, I'm going to stick with the default key bindings.

To start a new tmux session, just type
tmux

If you want to give the session a name, you have to also use new, then -s <session_name>, for example
tmux new -s copy

Screen only splits a screen vertically, that is, with one session on top and the other on the bottom. There's a patch for a horizontal split, but I haven't used it. Tmux has both options by default.

So, to split a screen vertically, as we did before.
C-b "

That is, hit the default combo of Control+b and ", the quotation mark. (Shift+' if you want to be specific). The screen will split, giving one session, called a pane, on the top, and one on the bottom. To split it horizontally, to have one pane on the left and the other on the right, use % instead of ". There are some predefined splits, which can be cycled by, once you've created two panes, C-b <space>. They are even vertical, giving both windows equal space, one top, one bottom, even horizontal, doing same for left and right, and main vertical, main horizontal, which gives one window the majority of the space, with the other (or others), getting much less space. To kill a particular pane, you can either type exit, which will close the pane, going back to the remaining pane or panes, or use C-b x which will confirm before closing the pane.

The panes can be resized. Hit C-b then Control and up or down arrows for panes split vertically or left and right arrows for panes split horizontally. C-b o allows you to move between panes.

To detach a session, use d just as you would in screen, with C-b d. To list sessions, use tmux ls, (no - before the ls). To reattach a session, use -t as in target
tmux att -t <session_name>
Actually, tmux a will work.

Another way to do this is to use tmux att, which will attach the last session you were using. (Actually, this hasn't been consistent for me, sometimes, it just attaches session 0, regardless of the last session I was in. I haven't quite figured that part out yet.) Then hit C-b s which will list all sessions, numbered from 0. If it reattaches session 3, and you want to go back to session 0, just type in the 0 and it will take you there. If you want to go back to session 3, do the C-b s again, type in 3 and you'll be back at session 3.

While bored, I made a kludgy little script to make tmux use -r instead of att -s.
#!/bin/sh 
while getopts r: OPTION
do 
case $OPTION in

r) tmux att -t $2;;
esac
done

Call it whatever you want, such as tmuxer.sh, put it in your $PATH, that is $HOME/bin or perhaps /usr/local/bin. Then if you have two sessions, compile and copy, you can use it with
tmuxer.sh -r compile

In practice, I seldom use it. One quickly gets used to the different syntax.

Many of the keybindings are the same as screen's. As mentioned, both use d to detach a session. To have a new window in the same tmux session--that is, not a pane, but a whole new terminal screen--use c, just as one would in screen, save that if one sticks to the defaults, it's C-b c, rather than screen's C-a c. Like screen, tmux uses p and n to navigate between windows with C-b n and C-b p.

Copying, using defaults, is also pretty straightforward. (I don't know how to do this in screen, or if screen even supports it.)

In the first pane go to the beginning of what you want to copy, and hit C-b-[, that is control, b, and the left side square bracket, [. Hit control, space and select what you want to copy with the arrow keys. When done, hit alt+w as in write, to copy the region.

Now, using C-b and o to get to the pane to which you are going to copy, use C-b-] (the right square bracket), to paste.

Another useful option is to move a pane from one window to another. Suppose I have a session where I'm running 3 panes in one window and 1 pane in a second window. If I look at a window, there will be an asterisk after the window that I'm in, so that if I were running a total of 4 ssh sessions, (3 in one window and 1 in the second), and I'm focused on the second window, I will see at the bottom of the tmux screen
[0]1:ssh- 2:ssh*

(It may be somewhat different depending upon how many different windows I have open and what I'm doing in each. Not every non-used window will have the -, but the active window will have the asterisk after it. In this case, I want to move one of the ssh sessions from window 1 to window 2 so that I will have 2 sessions in each window.

First I hit the usual ctl+b. Now I hit : (a colon) to show that I want to run a command. I then type
join-pane -s 1.0 -t 2.0

This will take the first pane in window 1 and make it the first pane in window 2. You can see your pane numbers by typing ctl+b, a colon to indicate you're typing a command, then display-panes. If you have them stacked from top to bottom, generally the top one is 0, the next 1, and so on. In the example above, I moved the top pane to the next window, but the reader can move whichever pane or panes they desire. You can also use ctl+b and an exclamation mark, !, to break a pane--that will move the pane in focus into its own window.

Regardless of whether the reader uses screen or tmux, a terminal multiplexer can turn out to be incredibly useful. This simple tutorial doesn't cover everything they can do--one can, for example, rename windows, swap panes and many other things.