Solved

Script to auto-kill idle users and email admin and/or user

Posted on 2004-09-30
11
2,175 Views
Last Modified: 2013-12-06
Running HP-UX11.0, I've been playing with some of the scripts from a few posts. I'm looking for a script I can run as a cron to kill old pts sessions and then email myself and possibly the user.

I'm able to email myself the results of a w or a who -u, but can't get the kill portion working.


Using the following (tfewster's script from a previous post Thanks!):

#!/usr/bin/ksh
# myscript
mv /tmp/idle /tmp/idle.old
who -u | awk '
$6 == "old" {print $1 ,$2}
$6 ~ /:/ { if ( substr($6,1,1) > 0 ) {print $1,$2}}
' > /tmp/idle

diff /tmp/idle.old /tmp/idle | grep "^>" |awk '{print $2 $3}' > /tmp/idle.new

while read user tty
do
  echo "The (pseudo) terminal is " $tty | mailx -s "Idle for > 60 minutes - Please log out" ${user}@mail.com
done < /tmp/idle.new

**************************
I now get for the ${user} variable = username+tty (e.g. jdoepts/ttb@mail.com instead of jdoe@mail.com)
and the $tty is null in the mail message. And if I could tie an email using mailx in would be great!

Maybe something like a "w" output but only showing the users killed:
************************************
w > /tmp/activeprocesses.txt
if [[ -s "/tmp/activeprocesses.txt" ]] then    
   echo Mailing list of idle users to admin
   cat /tmp/activeprocesses.txt | mailx -s "Idle User Sessions Killed at $DATE" $SYSADMIN
0
Comment
Question by:Psychotic_ldc
  • 4
  • 3
  • 2
  • +1
11 Comments
 
LVL 20

Expert Comment

by:tfewster
ID: 12193578
Dammit, another newbie awk error by tfewster...
Use:
diff /tmp/idle.old /tmp/idle | grep "^>" |awk '{print $2 " " $3}' > /tmp/idle.new

(Needed some sort of seperator between the 2 "fields" when printing; Otherwise the next step [`read`] won't recognise it as 2 seperate parameters)

I'll post this in the original Q - Feel free to get Community Support to delete this & refund your points
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 12193608
hmm, my HP-UX knowledge is a bit outdated, but AFAIK who is very strange on HP-UX
I'd use
   who am i -R
that should return something like:

user      pty/ttys0    Sep 30 07:40  (host)

using awk to pars that, you get the user in $1 and the tty in $2

Does this help?
0
 

Author Comment

by:Psychotic_ldc
ID: 12195395
I've taken your script a bit further:

***************************************
#!/usr/bin/ksh
# myscript

SYSADMIN=admin@mail.com
DATE=`date`

mv /tmp/idle /tmp/idle.old
mv /tmp/idle.email /tmp/idle.email.old

who -u | awk '
$6 == "old" {print $1 ,$2, $3, $4,$5,$6,$7}
$6 ~ /:/ { if ( substr($6,1,1) > 0 ) {print $1,$2,$3,$4,$5,$6,$7}}
' | sort > /tmp/idle

#To avoid mailing the user repeatedly, just extract the new entries on the idle list
diff /tmp/idle.old /tmp/idle | grep "^>" |awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}' > /tmp/idle.new

echo " Inactive users at $DATE" >> /tmp/idle.email
while read  user tty test3 test4 test5 inactive pid
do
  echo "User: " $user ", the (pseudo) terminal is " $tty" Inactive for " $inactive | mailx -s "Idle for > 60 minutes - Please log out" $user@mail.com
  echo "User: " $user " - Time Inactive: " $inactive " - PID: " $pid >> /tmp/idle.email
done < /tmp/idle.new


cat /tmp/idle.email | mailx -s "Idle Users at $DATE" $SYSADMIN
# You may like to treat "old" entries differently, and just kill them.
*************************************
Now I just need a way to add the kill to use the PIDs within the script...
0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 20

Accepted Solution

by:
tfewster earned 500 total points
ID: 12195928
This is where it gets slightly risky, as you may be killing a valid process or killing processes in the wrong order...So I suggest "monitoring" the system usage using the previous suggestions and friendly email warnings for a few weeks...

For phase 2 (no more Mr. nice guy):
while read  user tty test3 test4 test5 inactive pid
do
  ps -ft  $tty | awk '{print $2}' | sort -nr | xargs kill
done

(ps -ft tty gets all foreground processes on that terminal; the trick is to kill them correctly)

BUT: I suggest getting `idled` from http://www.darkwing.com/idled/  - It's configurable and far more sophisticated than my simple suggestions!
 

0
 
LVL 38

Expert Comment

by:yuzh
ID: 12196106
You need to defined how long the user is Idle before  killing their process (excluding root).

You can do:

# list users idle for more than 15 minutes, not including root
w | grep -v idle |awk '$1!~/root/' | awk '$4 > 15 {print $1, $4}'

or:

# same as above, but force line to contain "pts"
w | awk '$2~/pts/ && $4 > 15 && $1!~/root/ {print $1, $4}'

You might want to print the tty infor so that you can use "kill + grep +ps"

w | awk '$2~/pts/ && $4 > 15 && $1!~/root/ {print $1, $2, $4}'
0
 
LVL 38

Expert Comment

by:yuzh
ID: 12197103
Any reason?
0
 

Author Comment

by:Psychotic_ldc
ID: 12200230
tfewster,
kill portion works great. Get an echo of:

usage: kill [ -signo ] pid ...

for each process it kills, but it does kill it. All of my users use a single tty session to acces a DB using a terminal emulator.

see total script thus far:
******************************

#!/usr/bin/ksh
# kill_idle_script

SYSADMIN=me@mail.com
DATE=`date`

mv /tmp/idle /tmp/idle.old
mv /tmp/idle.email /tmp/idle.email.old

who -u | awk '
$6 == "old" {print $1 ,$2, $3, $4,$5,$6,$7}
$6 ~ /:/ { if ( substr($6,1,1) > 0 ) {print $1,$2,$3,$4,$5,$6,$7}}
' | sort > /tmp/idle

#To avoid mailing the user repeatedly, just extract the new entries on the idle list
diff /tmp/idle.old /tmp/idle | grep "^>" |awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}' > /tmp/idle.new

# You may want to grep "root" out of this list. We're allowed to break the rules :-)

echo " Inactive users at $DATE" >> /tmp/idle.email

while read  user tty test3 test4 test5 inactive pid
do
  echo "User: " $user ", the (pseudo) terminal is " $tty" Inactive for " $inactive | mailx -s "Idle for > 60 minutes - Please log out" $user@mail.com
  echo "User: " $user " - Time Inactive: " $inactive " - PID: " $pid >> /tmp/idle.email
  # This step kills the user
  ps -ft  $tty | awk '{print $2}' | sort -nr | xargs kill
done < /tmp/idle.new

# Send email of all PIDs killed to admin
cat /tmp/idle.email | mailx -s "Idle User Processes Killed at $DATE" $SYSADMIN

*********************************************************

yuzh, already have the idle users > 60 minutes in the script itself.
0
 

Author Comment

by:Psychotic_ldc
ID: 12200247
forgot to comment out the:
echo "User: " $user ", the (pseudo) terminal is " $tty" Inactive for " $inactive | mailx -s "Idle for > 60 minutes - Please log out" $user@mail.com

since we would actually kill their process. Just comment out either this line OR the kill line depending upon how mean you want to be. :)
0
 

Author Comment

by:Psychotic_ldc
ID: 12201524
Still having a bit of trouble awking out certain usernames so they don't get killed.
e.g. how would I exclude "jdoe" username in the script above? Thanks for all the help!
0
 
LVL 20

Expert Comment

by:tfewster
ID: 12203495
grep -vE "root|jdoe|user2|etc" /tmp/idle.new > /tmp/idle.new2 && mv /tmp/idle.new2 idle.new
0

Featured Post

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

My previous tech tip, Installing the Solaris OS From the Flash Archive On a Tape (http://www.experts-exchange.com/articles/OS/Unix/Solaris/Installing-the-Solaris-OS-From-the-Flash-Archive-on-a-Tape.html), discussed installing the Solaris Operating S…
Java performance on Solaris - Managing CPUs There are various resource controls in operating system which directly/indirectly influence the performance of application. one of the most important resource controls is "CPU".   In a multithreaded…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:
In a previous video, we went over how to export a DynamoDB table into Amazon S3.  In this video, we show how to load the export from S3 into a DynamoDB table.

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question