by Chris Lumens
March 24, 2004
screen is a terminal multiplexer: it takes many different running processes and manages which of them gets displayed to the user. Think of it as a window manager for your console or terminal emulator. With screen, you can have interactive processes running on your home computer and connect to them from anywhere else to check on their progress. What sorts of programs are good for running in screen?
There are three different ways you can think about what screen is displaying to your console. We'll need to be familiar with the meaning of these terms for the rest of the presentation:
Additionally, it helps to know what the following mean:
screen tries to stay out of your way as much as possible. Just about everything you type gets sent to the running program. This makes interacting with screen a little bit weird. All screen commands begin with control-a, which will be abbreviated with ^A. Anything you're supposed to type will be shown in the white-on-grey scheme. After you give it the ^A, you give a command key which tells screen what to do. ^A ? brings up a list of all the possible commands, while ^A : brings up a command prompt that you can use to type commands and set variables. All the command keys have a full word equivalent that you can type.
You make a new session on the command line. Without any options, screen will make a new session and run your $SHELL inside it:
This session will be named with the PID, TTY, and hostname where the session was started. Not very descriptive or exciting. Luckily, you can easily give the session a name:
$ screen -S edonkey
If you start up a screen session and forget to give it a name, don't worry. You can use ^A :sessionname <name> to give it a name. Note that the session names have nothing to do with window names, as we will see later. Finally, you can have screen start a program other than $SHELL with the common option:
$ screen -e pine
So you're sitting there recompiling your distribution when you see it's time to run to class. You'd like to be able to check out the progress later from a lab. Luckily, you started the compile up in a screen session. To be able to attach to it later, you first need to detach from it here, with ^A d. The compile session will disappear, and you'll be back at the prompt that you started screen from.
There are ways to attach to a running screen session you forgot to detach from. Those will be covered later.
The opposite operation from detaching is attaching, which is where you reconnect to a previously detached session. If you've only got one session running, it's very easy to attach to it:
$ screen -r
However, it's possible that you have many sessions running at once. In that case, you'll need to tell screen which session to attach to. Of course, first you will want to know what the possibilities are. Luckily, screen has a command line option to list running sessions:
$ screen -ls There are screens on: 15150.uml-slk (Detached) 18614.uml-fed (Detached) 2 Sockets in /tmp/screens/S-root.
Then you just specify the name or PID of the session after the -r command line option and that session will be attached. You can see why you might want to name things beforehand, especially if you have lots of stuff running.
Running several sessions is handy but switching among them can be a pain, since you have to detach and reattach all the time. A better option is to run a single session with several windows inside it. As you'll see, switching among many windows is very quick and powerful.
Making a new window is easy. Just hit ^A c. screen will start up a new active window and run $SHELL in it. Your previously active window will be hidden from you, but any programs on it are still running. If you detach a session with many windows in it, all programs on all windows will continue running. When you reattach, the active window will be displayed again.
The most difficult thing about lots of windows is keeping track of them. The default display doesn't show you anything about what windows are open or what programs are running in them. When you switch from one window to another, the previous one just disappears. Luckily, screen provides many ways to keep track of all your windows.
Windows can have names, just like sessions. The default window name is the program running in it, which will usually be $SHELL. Renaming windows will help you keep track of them, and is done with ^a A. screen will display a prompt at the bottom for you to provide a name.
A simple way to list all your windows is ^A w, which just gives you all the names and window number along the bottom of the screen. This line also displays some status information, the most important being that the current window is marked with an asterisk. This is just a list, though; there's no way to switch. If you want to pick from a list, you can use ^A ", arrow down to the window you want, and hit return. Or if you know the window number, ^A 0-9 will bring that window up. As we'll see later, there's a way to have a continuous window list display. This combined with switching on a number is the fastest way to move around.
Finally, you've got screen regions. Just like vim can split the display up into several areas, so can screen. You can split the window up into two equally sized regions with ^A S. The already running program will get squashed into a region half its original size, and a new region will open up on the other half. This new region will have nothing running in it, since you might want to stick one of your currently running windows inside it.
There's several ways to change focus among regions, but the simplest is the obvious ^A <tab> Once you're in the new region, you can display any of your windows in that region just by switching to them with ^A 0-9, or you can create a new shell in that region with ^A c.
And last, you might get tired of all these regions clogging up your window and want to kill them. You can make the current region the only visible one with ^A Q, which simply hides all the other regions and makes them accessible via the window numbers. Or, you can kill off the current region entirely with ^A X. Note that hiding a region keeps programs running, while killing a region kills any programs running in it.
screen quits when everything running inside it quits. This means you'll need to step through all your windows and kill the shells running inside them with ^D or exit. Usually, this is exactly what you want. Sometimes, though, you might want screen to just go away immediately. ^A ^\ will kill screen, and everything running underneath it. That means all the shells running on all the windows, and all the processes started by all those shells. That's certainly not a command you want to use too often.
Sometimes, you might be at a remote location and want attach to a session that you'd forgotten to detach from earlier. You're not out of luck, because screen provides you a couple ways to handle this situation. The first approach is:
$ screen -x src
This attaches to the src session without detaching first. So in other words, you've got two sessions looking at exactly the same thing. Anything you do on one session will be displayed on all of them. When you're done, detaching from the one session leaves the other attached. It helps to have the same terminal type and size to do this, though.
You can also use one of the six -D -R option combinations described in the screen man page to detach any active sessions before attaching again.
Digraphs are characters that take us several keystrokes to type, because our keyboard doesn't have the right symbols. Good examples are European letters and international money symbols, like ë, ø, and Æ. X supports these characters with the compose key, which you can map to any spare key you've got on your keyboard. screen provides similar functionality with the digraph command. Just type ^A ^V followed by the characters that make up the digraph. The three characters I made above are done with:
screen's digraph list is built-in, so you can't yet add your own. Note that ^V is also the vim insert mode command that allows you to put control sequences into your files.
Say you've got a whole bunch of windows open. One of those windows is idling in a very inactive IRC channel. Since not much goes on in there, you don't keep that window active but you would like to know when something is said. screen lets you monitor any window for activity by first switching to the window, and then hitting ^A M. When activity in that window occurs, screen will display a message at the bottom.
On the other hand, say one of your windows is a compile of X. There's lots and lots of activity and you'd like to know when the build is finished. You can monitor for 30 seconds of inactivity by switching to the window and hitting ^A _. When the window goes silent, screen will display a message at the bottom.
These monitoring commands are toggles, so you can turn them off by switching to any monitored window and issuing the command again.
Yes, it is possible to have screen sessions inside each other. This can be really confusing, so I'm only mentioning it so you know it's possible. One problem with nested screens is sending the ^A to one of the nested sessions, since the most outside session will interpret the key and not send it where you wanted. In this case, you need ^A a which simply sends ^A to the running program, which might just be another screen. If you had one screen inside another and wanted a list of windows on the inner one, you'd need to do ^A a w.
Finally, screen allows several users to connect to a single session at the same time. It provides an access list for the session and allows you to set read/write/execute permissions for each user on that list. It even provides a way to set up user groups. One good reason for this multiple user feature is that you can interactively have several people looking at some source code so there's no confusion as to what part you're talking about.
Before anyone else can connect to your screen sessions, you have to enable multiuser mode with ^A :multiuser on. Then, you give another user permission to connect with ^A :aclchg david +r "#". This means that the system user has read permission on all windows. You can specify multiple users, write and execute permissions, and certain windows. Be especially careful with the execute permission as that will let other people create new windows and change the acl permissions themselves.
Now the user you granted access to can connect with:
$ screen -r chris/
At any time, you can delete other users with acldel david. As with any system that involves multiple users, there are a lot of security implications and access features. Use carefully and see the man page for the details.
/etc/screenrc and $HOME/.screenrc are the screen configuration files, with the $HOME one overriding values set in the global one. You can experiment with settings while screen is running, and then move those settings into your .screenrc file to make them permanent. Just about anything you can type into screen can be added to the config file. I'm only going to touch on a few. See the man page for more.
Instead of beeping, the visual bell displays a message when something happens. The default screen message is " Wuff ---- Wuff!! ", which is pretty stupid. You can change this with the following line:
You can add your own commands that are bound to keys. For example, here's an example key binding that opens a new window with an ssh session to a different computer:
bind 'R' screen ssh root@foc-gw-1
Now hitting ^A R will open up a new window with an ssh session in it. As you can see, you still need to hit ^A to get screen to pay attention. Key bindings can get way more complicated than this, of course.
screen lets you modify the termcap entry without having to make up an entire new one by hand. I'm not really going to cover this, except to mention it. I don't really understand all the termcap stuff so I can't talk about it too much. But if you know that you need to edit the terminal settings, screen will let you do that. Here's an example out of the system default:
termcap vt100 dl=5\E[M
You can specify all sorts of windows to start up when you run screen. Just list them in your .screenrc file with the screen command, like so:
screen 0 ssh chris@ziggy -e pine screen 1 vim ~/src/manos/src/kern/GNUmakefile screen 2 ssh -X root@unit
Earlier, I mentioned that you could have a constant display of what windows are open, to make switching between them faster. You do this with the hardstatus line. By default, status goes up into the titlebar of an xterm, or down at the bottom of the screen on the console. However, you can force that status line to always stay at the bottom of the screen by adding this to your .screenrc:
hardstatus on hardstatus alwayslastline
Then you just need to set up a statusline string that displays the information you want. The following statusline displays a list of all the windows and their numbers on the left side, and the date and time on the right side:
hardstatus string "%w%=%m/%d %c"
Of course, these status lines can get much more complicated including colors, output of random programs, and so forth. See the man page section "STRING ESCAPES" for details.
screen is a complex and powerful program for managing interactive console programs, similar to how a window manager handles graphical programs. screen is more powerful than a window manager, though, because it allows you to attach and detach from the running programs as much as you want. I've only covered a few of its many features in this presentation. The man page is far more detailed.
This presentation is available at http://www.bangmoney.org/presentations/screen.html and is © 2004 Chris Lumens.