I'm about 50% of the way through this big mail migration project I've been going on abot for a while. I started in earnest in the middle of November after budget cuts, bureaucratic delays, hardware being out of stock, etc... (I suggested we do this move over two years ago and was told, "we'll think about it") So it's finally, "bye bye iPlanet and hello Zimbra" time. And I have to say that Zimbra got it right in every possible way so far. I posted some of my early Zimbra experiences on one of my recent Slashdot journals, so I won't go into that here. Same thing for the incredibly "too useful to be ignored" VirtualIron virtualization product that now uses the Xen microkernel. If you want to hear those comments look at my Slashdot journal that touches on it. What we're here for today is the GNU 'screen' utility which I'm sure some of you must be familiar with.
Way back in 1997 I was running my own Quake server for LAN parties with my friends. One of my frustrations was that I had to leave a Putty session open and connected to the server at all times because there didn't appear to be a way to background the server and then reconnect to it later. I posted about this somewhere and someone said "use GNU screen". I took one look at it, didn't get it and didn't bother to look at it again for some time. I think sometime around 2001 I had a need to run a process in the background that I could come back and interact with. This time it was for work and I couldn't just walk away from the problem. Someone in another forum recommended GNU screen again. So I read the man page with little more interest and then tried it out. In short, the most basic use for it is to be able to run a virtual terminal session that you can disconnect from and re-attach to. Another way of putting it is that it is like VNC for the command line. But in reality it's so much more than that.
If you're new to 'screen' you'll wonder why the hell I'd want to use something like this when there are things like xterms, gnome-terminal, konsole and the like. The only way to really understand is to try it out for yourself. An excercise (make sure you have 'screen' installed on your box first):
1. Pop open a terminal window and type 'screen'. This will launch the application and you'll see a prompt just like you usually do. It will probably look like nothing happened. That's OK. Just have faith.
2. Now start a process that will continue to run in screen. ping an IP on your network or the internet, or run 'top'. Those should illustrate the basics nicely.
3. Now that you see something running and constantly updating on the screen, press this key combination: Ctrl-a d (That is Ctrl-a first then an individual 'd'). The process you started will appear to have quit. But it hasn't...
4. Now press Ctrl-Alt-F1 to get to the first virtual console on your box. Log in as the same user that spawned the 'screen' process and type 'screen -ls'. Look for the screen PID number in the output.
5. Once you have the PID, type 'screen -R pid'. This will re-attach you to the process you left running from the terminal emulator in X earlier. If it was 'top' you should still see it updating.
6. Stay attached to this virtual console, then press Alt-F7 (assuming that your X server is on VT7) to switch back to X.
7. In X, bring up a GUI terminal like xterm, gnome-terminal or konsole and enter the following: 'screen -x pid'. Make sure to use the same exact PID you used before. You should see your process running, and you're also still connected from virtual terminal 1 as well. The -x option allows you to connect to a screen instance that already has someone else connected. It's a great way to train someone or classroom full of someones, or to handhold someone who is trying to troubleshoot a problem.
These are just the bare basics of 'screen'. It can do a lot more if you delve into it deeper, especially if your a CLI rider like me. (Funny about that, I used to say that Unix was dying back in 1994 when I got my first Windows box) Read on for more fun with 'screen':
The Scrollback Buffer (Copy mode):
How many times have you been at virtual console #1 through #6 and had no access to X (it's borked or something) and when you have a bunch of text fly past you during a compile or other heavy text stream you think, "I wish I had a scroll bar right now". Well, wish no longer. 'screen' might not give you a scroll bar, but it does give you a very nice scroll back buffer. Assume that you're already in 'screen' and that you had that text fly by and really want to see what went past you. Assume that you're not in a GUI.
1. Press Ctrl-a ESC to enter copy mode
2. Now use the up/down, left/right, page up/page down keys to move around in the buffer. Go up as high as you can (I believe the default limit is 1000 lines, but you can change that by starting screen with the -h argument: 'screen -h 4000') and marvel at this ability.
3. But it gets better... You can do forward or reverse searches within this buffer by using / or ? respectively. Example:
This search will find any occurences of the word error from your current position to the bottom of the buffer:
This search will find any occurences of the word error from your current position to the top of the buffer: ?rror
4. And even better... While you're in copy mode, you can also select and copy text to screen's paste buffer. Move your cursor to where you want you selection to start and press the space bar. Then move to the bottom of what you want to select and press the space bar again. This will place a copy of the selected text in screen's paste buffer and exit copy mode. To paste what you selected: Ctrl-a ]
Logging Your Sessions to a File:
1. Press Ctrl-a : to enter into screen's command mode. This will provide you with a prompt in the bottom left that is simply a colon.
2. Specify the path you want screen to log to using the 'logfile' command. If the file doesn't exist, it will create a new one.
3. Turn logging on: Ctrl-a Shift-h
4. Do your stuff...
5. Turn logging off: Ctrl-a Shift-h
This feature has come in very handy for my work recently...
Within one instance of screen it is possible to have more than one terminal and switch between them (kind of like Alt-Tab to switch between various windows in a GUI). Here's how:
1. Start a screen instance with a useful name and a good scroll back buffer:
screen -S MailMigration -h 5000
2. Name the first "window" by pressing Ctrl-a Shift-a then deleting the default "bash" in the bottom left and replacing it with something useful. In my case I've named window 0 "iPlanet".
3. Now spawn a new "window" by pressing Ctrl-a c and then give it a useful name. This is "window" 1 and in my case I've named it "Zimbra logged in as zimbra user"
4. Spawn one more window again using Ctrl-a c and give it a useful name again... My "window" 2 is called "Zimbra logged in as root" (Yeah I know... not the place or time)
5. Now that you have three "windows" with useful names, let's look at them. Press Ctrl-a " and then use the up/down arrow keys to move through the list and select the "window" you want, then press enter. You can verify that these are all different windows by doing something different in each and then switching between them.
6. One more neat trick... you can quickly switch between the current window and the previously selected one by pressing Ctrl-a Ctrl-a This is immensely useful if you're having to compare things between two systems and don't have any option to do it from the GUI or just want to be able to pick up where you left off later by reattaching to the screen instance.
A Small Sample of Really Batshit Insane Stuff You Can Do With GNU screen:
If you have a detached screen running something that you would like to interact with but don't really need to connect to screen to do it with, you can use the -X argument followed by the internal screen command you want to execute. In my case, I have mplayer running within a screen session happily playing a playlist for my alarm clock in the morning. I want to send it a "space" bar without having to attach to screen to actually do it. So I have my script do this:
screen -p0 -X eval 'stuff \040'
In my real script I've named my screen instance by starting it with:
screen -S Alarmclock
So to send the space bar to the detached screen, I actually do this:
screen -p0 -S Alarmclock -X eval 'stuff \040'
The -p0 is needed to say, send it to screen's
The -X eval 'stuff \040' causes screen to intercept that command, process the 'stuff' command which then sends ASCII char 040 (the space bar) to mplayer. I'm using this to create a "snooze" feature in my alarmclock script (don't ask just assume that I'm insane).
There's a hell of a lot more, but this is a small sampling of how GNU screen just rocks.
Side comment: I have to wonder how long it will be before Microsoft "innovates" something like this but missing about 90% of the features. They've been making moves to try and lure people away from *nix (like PowerShell) so I imagine that if people see the light about 'screen' and it becomes more popular, MS will try and duplicate it. And get it wrong. Again.