Cover V14, i04

Article

apr2005.tar

Using Screen in Scripts

Ed Schaefer and John Spurgeon

We expected reactions to our "Using Unknown Passwords" column, and we were right. We'll cover reader feedback before continuing with this month's column.

Revisiting "Using Unknown Passwords"

Readers Andrew Barber, Rob Tanner, and Christopher Baker asked about situations when you really need root's password. At OS boot-up, what happens when you are queried for root's password to execute fsck or to enter a different maintenance mode or run-level?

Depending on the situation, you might have to boot from external media to solve this problem. In our environment, we support systems consisting of a primary, a secondary, and a backup server. In the event of a boot problem, we promote our backup server to be the production server and fix the problem at our leisure.

In Baker's situation, at times he requires the actual root password for maintenance purposes, such as clearing screen locks and installing software. If a user has root privileges through sudo, that user has the ability to temporarily change root's password. Simply become root, execute "passwd root", and set a new password.

If necessary, the cron jobs that set passwords to random values can be temporarily disabled as well. (Although the column suggested changing root's password every minute, that's probably overkill in most situations.)

Carl Lowenstein suggests locking root's password instead of using our complicated procedure to periodically change the password. Lowenstein raises another excellent point -- one that we should have stressed in the article.

On Solaris, you can lock a user's password with the command:

passwd -l username
This inserts the string "*LK*" in the encrypted password column in /etc/shadow. This might be just as good as setting the password to a random value, provided you also turn off password aging with the command:

passwd -x -1 username
On Solaris, you have to be careful because if a user's password expires -- even if it is locked -- that user's cron jobs stop running. Since we don't know whether there are other unanticipated consequences of locking a user's password, we feel more comfortable setting the password and changing it on a regular basis before it expires. Now, let's move on to this month's column.

Using Screen in Scripts

In "Using Screen" (http://www.samag.com/documents/s=9142/sam0405f/), Robert Bernier introduced screen, a powerful window manager and showcased its potential by addressing the major features. In this article, we will present some of the ways we have used screen in scripts to solve systems administration problems. We will discuss how to automate the use of screen, how to start programs in detached screens (and why you might want to), and how you can use sudo to share screens between users.

Automating the Use of Screen

Screen is useful when running programs that take a while to complete -- if you remember to use it. Suppose you're working from home and you need to start a program to archive a large database on a server at the office. You connect to the server remotely, log in, and start the archive program. Even though you have screen installed, you forget to use it, so you can't disconnect from the server without killing the archive job. An hour later, just as the job is about to complete, a squirrel chews through a cable, you're disconnected from the Internet, the archive process is killed, and you have to start all over again. If you had remembered to run the archive program in a screen, you could have detached the screen after starting the job, and it would have completed regardless of whether you were connected to the server.

One way to automate the use of screen is to create a wrapper script:

#!/bin/ksh
# file name: my_program.ss

# Try attaching to an attached screen
if ! screen -x my_screen >&- 2>&-
then
    # Try attaching to a detached screen
    if ! screen -r my_screen >&- 2>&-
    then
        # Start my_program in a new screen
        screen -S my_screen my_program
    fi
fi
# end my_program.ss
Instead of calling my_program directly, execute my_program.ss, which will run my_program from within a screen named my_screen. If two or more people are logged in as the same user (e.g., dba), and one of them is running my_program in an attached screen, then subsequent invocations of my_program.ss (by dba) will automatically attach to the already attached screen session. Similarly, if my_program is already running in a detached screen, then calling my_program.ss will reattach the detached screen session.

Starting Programs in Detached Screens

When a system boots, several programs are executed as startup scripts. It's only after most of these scripts have completed that a login prompt is displayed on the console. A startup script that takes a long time to complete can delay logging in. Worse, a startup script that hangs can prevent logging in all together.

To reduce the time it takes to display the initial login prompt, and to prevent boot problems, it may be desirable to run certain startup scripts from within a detached screen session. A typical example is starting a database engine, which can be an extended process. While it's important for the engine to start, it may not be important to delay the boot process until the engine is online.

Here's a one-line startup script that runs a program called dbstart in a detached screen session named dbstart_screen:

#!/sbin/sh
# File name: /etc/rc2.d/S99dbstart

screen -m -d -S dbstart_screen dbstart
The -m -d options tell screen to start in detached mode. This creates a new session but doesn't attach to it.

Now the boot process can continue while the database engine starts. If the dbstart command hasn't completed, the administrator can log in after the system boots, reattach to the screen session, and monitor the progress of the dbstart command.

Occasionally, you might encounter programs that fail when run as startup scripts or as cron jobs, because they expect to be executed from within a terminal. You can work around this type of problem by running these programs in detached screen sessions. If you want a contrived example of a script that expects a terminal, create one that writes to /dev/tty, such as:

echo "Goodnight, Moon" > /dev/tty
Using sudo to Share Screens

If screen is installed setuid-root, then users can share screen sessions with each other. The process is fairly simple. A user who wants to share a screen executes a couple of screen commands, such as multiuser on and addacl username. These commands can be invoked manually from within a screen session, or they can be part of a screenrc startup file.

Experienced screen users should be able to share screens without any trouble. However, for a complete novice, the process presents a learning curve. Here's an alternate technique for sharing screens that is extremely easy to use:

#!/bin/ksh
# path: /usr/local/bin/share_screen

screen_name=${1:-share_screen}

if ! /usr/local/bin/screen -x "$screen_name"
then
    /usr/local/bin/screen -S "$screen_name" \
    /usr/local/bin/ssh $(logname)@$(uname -n)
fi
# end script
The trick is to use sudo to give users the ability to execute the script as root. If you're catering to novices, you might want to create an alias, too. For example:

share_screen='sudo /usr/local/bin/share_screen'
Assuming the above alias is in effect and the appropriate permissions have been granted in /etc/sudoers, a user who wants to share a screen session would only have to type:

share_screen [screen_name]
The first person who executes the command with a given screen name is prompted to log in to their own individual account. Because the new screen is owned by root, this step is necessary to prevent users from obtaining a command prompt with root access. Subsequent users invoking share_screen with the same screen name connect to an already attached screen session. In our example, we are using ssh to log in, but telnet or rlogin could be used as well.

This technique for sharing screens works regardless of whether screen is installed setuid-root. It also allows users to share screen sessions after using su to become another user. Normally, if you become another user besides root, you can't attach to a screen session due to the permissions on the terminal device files.

References

Bernier, Robert. "Using Screen", Sys Admin, May, 2004 -- http://www.samag.com/documents/s=9142/sam0405f/

Online MAN page for screen -- http://software.oit.pdx.edu/cgi-bin/hman-local?ManSection=1&ManTopic=screen

John Spurgeon is a software developer and systems administrator for Intel's Factory Information Control Systems, IFICS, in Aloha, Oregon. Outside of work, he enjoys turfgrass management, triathlons, and spending time with his family.

Ed Schaefer is a frequent contributor to Sys Admin. He is a software developer and DBA for Intel's Factory Information Control Systems, IFICS, in Aloha, Oregon. Ed also hosts the monthly Shell Corner column on UnixReview.com. He can be reached at: shellcorner@comcast.net.