user1507
user1507

Reputation: 41

Kill a Long Running User Process in Linux using shell script

I need a shell script for killing a long running user process(which exceeds certain amount of time).

These are my observations regarding this:

  1. The script doesn't kill any daemon process
  2. The script needs to identify the list of users and needs to check whether it is a daemon process or not?For that we can check the terminal in which the process depends(In general daemon process doesn't depends any terminal)
  3. The Process id and name needs to be gathered automatically through the script.For that first needs to get the Elapsed time of all the process and check with our limit of time,from here we filterout the list of process which are excedding our limit and check with whether it depends with any terminal and under which user the process runs.
  4. Before deleting the process we need to get the confirmation whether i can kill the process or not?

This is what I've tried:

user = " " " " 
for i in user
  users="user1 user2 user3" 
  for u in $users ; do 
    ps -o etime,pid,comm -u $u | grep "here what i need to grep?" | while read in ; do 
    ET=`echo $in | cut -f1 -d":"` 
    [[ $ET -ge 10 ]]&&{ PID=`echo $in | cut -f2 -d" "` ; kill -HUP $PID ; } 
  done 
done 

Help me

Upvotes: 1

Views: 3426

Answers (1)

John1024
John1024

Reputation: 113814

This will kill -HUP any process that (a) belongs to a user on the specified list, (b) is not attached to a terminal, and (c) is more than 10 minutes old:

#!/bin/sh
users=("user1" "user2")
for user in "${users[@]}"
do 
    ps -o etime,euid,pid,tty,comm -u "$user" | while read etime euid pid tty comm
    do 
        [ "$etime" = ELAPSED ] && continue
        [ "$tty" = '?' ] && continue
        do_kill=$(echo "$etime" | awk -F'[-:]' 'NF==3{sub(/^/,"0-")} $1>0 || $2>0 ||$3>=10 {print "Kill"}')
        [ "$do_kill" ] || continue
        kill -HUP "$pid"
    done
done

How elapsed time is analyzed

ps delivers elapsed time in the format days-hh:mm:ss for jobs more than a day old or hh:mm:ss for jobs less than a day old. awk is used to interpret this and decide if the job is ten or more minutes old. That is done with the following command:

echo "$etime" | awk -F'[-:]' 'NF==3{sub(/^/,"0-")} $1>0 || $2>0 ||$3>=10 {print "Kill"}'

If the job is 10 or more minutes old, awk prints Kill. Otherwise, it prints nothing.

Taking each part of the awk command in turn:

  • -F'[-:]'

    This tells awk to break fields on either a dash or colon.

  • NF==3{sub(/^/,"0-")}

    If there are only three fields, then we add the missing day field to the beginning of the line. This assures that the next command sees a uniform format.

  • $1>0 || $2>0 ||$3>=10 {print "Kill"}

    If (a) the number of days, $1, is greater than zero, or (b) the number of hours, $2, is greater than zero, or (c) the number of minutes is greater than or equal to 10, then print Kill. Otherwise, nothing is printed.

Asking for confirmation before killing

The following prompts the user to OK applying kill -HUP to the process

#!/bin/bash
users=("user1" "user2")
exec 3<&0
for user in "${users[@]}"
do
    ps -o etime,euid,pid,tty,comm -u "$user" | while read etime euid pid tty comm
    do
        [ "$etime" = ELAPSED ] && continue
        [ "$tty" = '?' ] && continue
        do_kill=$(echo "$etime" | awk -F'[-:]' 'NF==3{sub(/^/,"0-")} $1>0 || $2>0 ||$3>=10 {print "Kill"}')
        [ "$do_kill" ] || continue
        echo "$user $etime $euid $pid $tty $comm"
        read -p "OK to kill this process (y/N)? " -u 3 ok
        [[ "${ok,,}" =~ y ]] || continue
        echo "Killing $pid"
        kill -HUP "$pid"
    done
done

Upvotes: 3

Related Questions