I found Larry Reznick's article "Timing Out Idle
1993 Sys Admin, vol. 2, no. 6, p. 43) extremely interesting
and valuable. When I read it, I was in the process of
C code to do the same task and was making no progress.
I was porting did have some limitations that I hoped
to overcome later,
but I preferred Reznick's approach using a shell/awk
script. For my
purposes, I decided to update his original work.The original killidle script scanned the /etc/utmp
file using the who(1) command. When it spotted a terminal
idle for longer than a predetermined time period, it
sent a SIGKILL
(-9) signal to the process ID (pid) and logged the action.
I've modified the algorithm a little to scan the /etc/utmp
file using the w(1) command -- more on why later --
for each login. I then look up the amount of idle time
the user, and if the amount of idle time is greater
than or equal
to the warning time, I send a warning message to the
login. If the
idle time is greater than or equal to the maximum idle
to the user, I send a message to the login about the
issue the kill via a SIGHUP (-1), which is a safer signal,
and log the kill action.
getparms (Listing 2) is a simple shell script that looks
a user and returns the maximum amount of idle time allotted
amount of idle time allowed before a warning should
be issued. The
script simply greps a priv.users file for the login
returns two fields in the record found: a maximum timeout
value and warning minutes value. If the login is not
in the file,
getparms looks for the keyword "DEFAULT" and
Figure 1 shows a sample priv.users file. In this sample,
user "mrg" gets 999,999 minutes (over 694
days) of idle time
before being warned or knocked off the system. The user
gets warnings after 540 minutes (9 hours) and killed
after 1,440 minutes
(1 day) of idle time. All other users get warnings after
and killed after 30 minutes of idle time.
I chose the w command over the who for two reasons.
First, I wanted to support idle times over 24 hours.
2 and 3, you can see the difference in the idle times.
With the who
command (Figure 3) idle times greater than 24 hours
by the keyword "old." The w command (Figure
the number of days the login was idle. Compare, for
example, the two
entries for pts/2.
Second, I wanted to warn my users that they've been
idle too long
and, if the session goes away, tell them why. If you
read the man
pages for both commands closely, you'll see a subtle
the interpretation of the idle field. The w command
to determine how long you've been sitting idle -- if
touch the keyboard for 10 minutes you're idle for 10
who command, on the other hand, uses screen activity
indication of idle time. So if a program displays a
message on a terminal,
that terminal's idle time would reset to 0 minutes even
was typed. It is for this reason that I chose to create
program (Listing 3) to display a message on the terminal.
If I had
used a conventional approach (i.e., written "some
> /dev/pts2"), then it would have been perceived
as terminal activity,
and the user idle time would be reset to zero. [Editor's
is a BSD command. It is included in many versions of
UNIX, but not
all. If your version doesn't have w, try whodo -l
as a substitute.]
Listing 1 shows the main program, idleout. You'll need
change the variable localpath to the directory where
to keep the getparms script and the wruser program
(more on wruser later). The first thing idleout does
is look up each user in the file priv.users using the
script. This lookup sets two idleout variables: warntime
and killtime. warntime is the amount of elapsed idle
time before warning messages are sent to the user; killtime
is the amount of elapsed time before the user is removed
Next, idleout takes the idle field from the w command's
output and converts it into a numeric value expressed
idletotal. If the total idle time is greater than the
wruser sends a message to the user's terminal telling
login's imminent death, the terminal is killed, and
a kill log file
is updated. If the total idle time is greater than the
but less than the killtime, idleout sends a warning
message to the terminal.
The wruser program takes two parameters, the terminal
to, without the /dev, and the message to be displayed.
recombining the message it searches through /etc/utmp
for a match for the terminal (ut_line holds the terminal).
Once the match is found, the /dev/ is prepended and
ID is stored. The write() function displays the message,
the pid is both printed and returned.
This is where it starts to get a little complicated.
I needed to execute
wruser from idleout's awk script and receive
wruser's return value back into the awk script. To
accomplish this, I form the command using sprintf, issue
command, and pipe the output to awk's built-in getline
function. getline reads the next line of input, in this
the printed output piped from wruser, and puts the result
in awk's pid variable.
idleout is designed to run as a root cron job. It
must run with root authority to allow wruser to open
Currently I run it every 2 minutes with the cron entry:
40,42,44,46,48,50,52,54,56,58 * * * * (sh /usr/user/idleout)
One last feature that's not in this version is the ability
change a user's killtime and warntime. The file priv.users
can be updated any time and the next time the script
is run, the new
file will be used. I'd like to see killtime and warntime
change according to what application the user is running.
an archie search can take over 20 minutes. With no keyboard
activity the session could be terminated due to a perceived
But that's for a future day.
About the Author
Matt Ganis is currently an Advisory programmer for
corporation, located in White Plains, NY where he works
networking. In his spare time he teaches Astronomy at
in Pleasantville, NY. He can be reached at 14 Udell
Manor, NY 10566 or firstname.lastname@example.org.