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. |