Hack #34. Disconnect Your Console Without Ending Your Session

Start a long-running job at work and connect to it from home or on the road.

Here's the setup: you're a Linux systems consultant with a busy schedule. It's 9 A.M. now, and you're already an hour into a very large database installation at one site, but you have to be at another site in about an hour. The build will never finish in time for you to thoroughly test it, create the developer databases, and set up security restrictions before you leave. What do you do?

One solution, of course, is to talk to your client and tell him you'll be back later to finish up. Another solution, however, may be to start the job in a screen session and log in later from wherever you happen to be to finish up. Lest you think that this will involve building yet another piece of software for your machines, take heart in knowing that screen is usually installed or readily available and prepackaged for whatever distribution you're running. You can also get more information on screen, including download information, at the GNU screen home page: http://www.gnu.org/software/screen/.

Getting started with screen couldn't be simpler. Just open your favorite terminal emulator and run the command, like this:

	$ screen

You will be greeted with a new shell, running inside a screen session. You can still talk to screen from within the shell, much like you can talk to any console terminal application from within a shell. The key combination you use to send input to screen instead of to the shell running inside the screen session is Ctrl-A. Ctrl-A in screen is similar to the Escape key in vi—it gets the application's attention so you can tell it what to do. For example, to access a quick command reference in screen, press Ctrl-A followed by ?.

The output should be a list of the many commands you can feed to screen. If you don't get any output, you can make sure you're actually in a screen session by invoking screen with the –list flag. You should see something similar to the following:

	$ screen –list
	There is a screen on:
			28820.pts-2.willy		(Attached)
	1 Socket in /tmp/screen-jonesy.

You can see from the output that there is a screen session running, to which we are currently attached. The process ID for this session is 28820, and we've been assigned to pseudo-terminal number 2. Now let's start a job that we can continue later from another location. A simple way to test the functionality is to just open a file in an editor such as Vim. Once you have the file open, press Ctrl-A followed by d, and you will be detached from the screen session and given back your plain old shell.

At this point, you can leave for your next appointment. Maybe at the next stop you have to do an OS installation, which leaves you with some free time while the packages are installing. Fire up your laptop, SSH to the machine where your screen session is running, and type screen –r to reattach to the session already in progress. If you have more than one screen session running, type screen –r pid, where pid is the process ID of the screen session to which you want to attach (discernible from the screen–list output we went over above).

Of course, trying to associate the process ID of a screen session with what's going on in that session can be a bit daunting, especially if you have lots of sessions running. Instead of doing that, you can name your session something meaningful when you launch it. So, when you launch screen for the purpose of kicking off a long-running software build, just type screen –S make, and the next time you attach to it, you can type screen –r make instead of trying to remember which process ID you need to attach to.

screen Scripting

If you manage more than a few machines, you've probably come up with some way of automating the process of connecting to some subset of your service machines at login time, or with a desktop icon, or by some other means that is more automated than manually opening up terminal windows and typing the commands to connect to each host. If you use SSH keys ( Hack #66 in the original Linux Server Hacks), you can create a simple shell script to automate this process for you. Here's an example shell script:

	#!/bin/bash

	screen -d -m -S svr1 -t jonesy@svr1 ssh server1.linuxlaboratory.org
	screen -d -m -S svr2 -t jonesy@svr2 ssh server2.linuxlaboratory.org
	screen -d -m -S svr3 -t jonesy@svr3 ssh server3.linuxlaboratory.org

Save this script to your ~/bin directory, and make sure you make it executable!

What makes this script work well is calling screen with the –d –m flags, which tell screen to start the session, but not to attach to it. Note as well that I've used –S to specify a session name, so when I want to attach to, say, svr1, I can just type screen –r svr1. In addition, I've used the –t flag to specify a title for my shell, which will show in the titlebar of my terminal emulator to help me keep track of where I am.

Warning

Running the above script will open up SSH sessions to, in this case, server1, server2, and server3. It might be tempting to put this into your shell's initialization script. Do not do this! In environments where home directories (and therefore, shell init scripts) are shared across hosts, this can create an endless stream of looping SSH sessions.

See Also

Get Linux Server Hacks, Volume Two now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.