2013-02-10

GNU Screen: short guide to making your terminal awesome

You use your terminal for everything nowadays. You have at least two terminal windows open at any time, probably closer to a dozen. You've customized the heck out of your shell's startup, and added so many aliases and functions you don't even know how you remember all of them. If that's you, and you haven't yet heard of GNU Screen or used it, you're in the right place.

Technically Screen is a terminal multiplexer, but you can think of it as of a tiling window manager for your terminals. It is closest to those tiling window mangers like awesome or ratpoison. The difference is, it doesn't manage X windows, but virtual terminal sessions.

I'll quickly walk you through basics and won't dwell on details, because they are pretty well documented, and then I'll explain the settings I used to make most of Screen.

Basic usage

Screen runs multiple shells, each in its own 'window'. It's not a true window like the ones you have in X window managers. It's just a bunch of virtual terminal sessions that you can switch between.

To start a Screen session, simply type this command:

screen

This sets you up with a single window with a shell. You'll notice the license information the first time you run screen. You can disable that by adding the following line to a .screenrc file in your home directory:

startup_message off

You can give your window a name. Use the key combination Ctrl+A Shift+A and Screen will prompt you for the new title.

To create a new window, use the key combination Ctrl+A Ctrl+C. This opens a new shell in its own window. To quickly switch between this and the other window, press Ctrl+A Ctrl+A (or hold Ctrl and press A twice). Each window has a number, and you can switch to a specific number by pressing Ctrl+A and then the number you want (release Ctrl before pressing the number). You can also list the windows by using the Ctrl+A " combination.

The terminal window in which Screen runs can also be split vertically and horizontally any number of times. To split horizontally, press Ctrl+A Shift+S. For a vertical split, use the Ctrl+A | combination. You can switch between the splits by pressing Ctrl+A Ctrl+I. You'll notice that new splits are empty by default. Use any of the window switching commands to load windows in them. To merge all splits back into a single window, you use the Ctrl+A Shift+Q combination.

There are a few ways to exit Screen. First of all, you can simply terminate/exit all active shells. That's the cleanest way to exit Screen (just like closing all running apps before logging out of your X session). A heavy-handed way to quit Screen is to press Ctrl+A \. There is a good reason you are prompted for confirmation in this case, because exiting Screen this way will kill all your shells.

Speaking of kills, another one of Screen's killer features is it's copy/paste system. At any time, you can press Ctrl+A Ctrl+[ to enter copy mode. This allows you to move around the buffer using Vi movement keys (hjkl). You can use copy mode to scroll back in the buffer, too. If you want to copy some lines, you just move the cursor to the first line you want to copy, press Y and then move around to select them. If you want to make a more precise selection, you can press V, then press Enter to confirm, then move the cursor around. Pressing Shift+Y will copy ('yank') the selection into the clipboard. You can then switch to anther window or otherwise move the cursor to the desired location and press Ctrl+A Ctrl+] to paste the yanked lines.

Detached Screen session and reattaching

You probably find GNU Screen very useful already, but it's true awesomeness comes from the fact that you can actually detach from a running Screen session, and reattach later without terminating any running programs. I will show you how to achieve this by explaining how I've set things up on my box.

I run Screen when I start my terminal emulator (urxvt). In my shell's rc file, I have the following line at the very end:

[ $STY ] || screen -x -S default || screen -R -S default

The $STY variable is set by Screen when you are inside a Screen window. I first check for this variable in order to prevent starting new Screen instances from within Screen (that would recursively create many new screen windows every time a shell is started inside Screen, which is not very useful). If the variable is not found, an attempt is made to attach to a non-detached Screen session (one that is running inside one of your terminal windows) by using the -x option. Failing that, we create a new session or attach to an existing but detached session (using the -R option). The -S names the session "default" (a completely arbitrary name) so we don't have to rely on process ID to find the detached sessions if any.

Let's go over using this simple setup.

When you first start your terminal, a new Screen session named "default" will be started. Since you are in that session, it's considered 'attached'. If you now start a new terminal, Screen will attach the to the same session that is running within the first terminal window. You will see the same things that you see in the first terminal, and anything you do in the first terminal will be shown in the second one, and vice versa.

Instead of exiting your terminal, you can either just close the window, or detach explicitly by using the Ctrl+A D combination. You would usually want to detach manually if you want to use the vanilla shell without Screen. At first, you may need to get used to not using the Ctrl+D shortcut unless you actually mean to close a Screen window.

Now, if you close all your terminals and open a new one, you will see that your Screen session is resumed. This will always be the case until you explicitly kill or quit Screen, or you log off your system. You can also drop into any of the system terminals (Ctrl+Alt+F1 through F12) and whenever you log into those terminals, you will see a resumed Screen session (provided that your shell's rc file is executed). This is even true if you log in remotely via SSH.

Showing the Screen window number

It's useful to know what window you are currently in. There are two ways to keep this information visible. One way is to add this line to ~/.screenrc:

caption always

Normally, the cation is only shown when you have split windows. With the above option, you can always display the window number and name.

Another option is to use the shell prompt. When you are in the Screen window, a $WINDOW variable is set, and contains the window number. For example, in shell's rc file, you can have something like:

PS1="[$WINDOW] ... rest of the prompt"

Further reading

You don't need much googling when it comes to learning more about GNU Screen. Manpage is a good starting point:

man 1 screen

Screen also has a help screen which is invoked by pressing Ctrl+A ? which lists keyboard shortcuts.