1829533 Members
1609 Online
109992 Solutions
New Discussion

Re: kill a process

 
SOLVED
Go to solution
Gerald Taylor
Frequent Advisor

kill a process

Hello I am not a scripting expert and would like to know the best way to grep and kill a process within a script. Any help will be appreciated. Thanks
10 REPLIES 10
Praveen Bezawada
Respected Contributor

Re: kill a process

Hi

Suppose you want to kill a java process you can do

PID=`ps -ef | grep java | awk '{ print $2 }'`
kill -9 $PID

This kill the java process.
James R. Ferguson
Acclaimed Contributor
Solution

Re: kill a process

Hi Gerald:

Here's one simple way to kill by process name:

TASK=/usr/local/bin/my.sh #...for example!

PIDS=`ps -ef|grep "$TASK"|grep -v "grep $TASK"|awk '{print $2}'`
#
if [ ! -z "$PIDS" ]
then
kill $PIDS > /dev/null 2>&1
sleep 5
kill -9 $PIDS > /dev/null 2>&1
fi

The idea is to kill, first gracefully (!) and then brutally the TASK(s) by name. The 'grep -v' eliminates finding the 'grep' process itself. The 'pid' of the TASK is isolated and used in the 'kill'.

Regards!

...JRF...
Magdi KAMAL
Respected Contributor

Re: kill a process

Hi,

I would modify the last response as follow :

PID=`ps -ef | grep -v grep ? grep java | awk '{ print $2 }'`

for currPid in PID
do
kill -9 $PID
done

java in the command "grep java" would be replaced by the process name that you are looking for.

This version run for multiple process killing under the same name.

Magdi
Praveen Bezawada
Respected Contributor

Re: kill a process

Hi

Sorry i missed
grep -v java

it should be
PID=`ps -ef | grep java | grep -v java|awk '{ print $2}'`
Magdi KAMAL
Respected Contributor

Re: kill a process

Oooops,

Sorry, kill command operates on $currPid and not $PID.

I would modify the last response as follow :

PID=`ps -ef | grep -v grep ? grep java | awk '{ print $2 }'`

for currPid in PID
do
kill -9 $currPid
done

java in the command "grep java" would be replaced by the process name that you are looking for.

This version run for multiple process killing under the same name.

Magdi
James R. Ferguson
Acclaimed Contributor

Re: kill a process

Hi :

Doing something like:

# PIDS=`ps -ef|grep java|grep -v java|awk '{print $2}'

...collects zero or more pids of "java" processes (at least those with the string "java" somewhere in the line returned).

'kill' allows a list of pids to be specified, so:

# kill $PIDS

...would kill the list in "one shot".

Regards!

...JRF...

Joseph Chakkery
Valued Contributor

Re: kill a process

Hello,

A for loop will be sufficient.

for Pid in `ps -ef | grep -v grep ? grep java | awk '{ print $2 }'`
do
kill -9 $Pid
done

Regards
Joe.
Knowledge is wealth
Bill Hassell
Honored Contributor

Re: kill a process

DON'T EVER GET IN THE HABIT OF USING kill -9!!

kill -9 will corrupt datafiles and leave a lot of work for application support to clean up. Kill -9 bypasses ALL of the program's code for graceful termination including flushing internal buffers, closing files correctly and writing appropriate messages to logfiles. Not all programs have this code but certainly databases and large scale data analysis do have this capability. kill -9 is used ONLY as a last resort. Use kill -15 (which is the default for kill)

I would also be VERY careful with using grep for finding process names. Using: "ps -e | grep java" will find all the lines in the ps listing with java INCLUDING user logins such as javabob and javaier, and process names such as java1 and w6javaw4....you certainly don't want to kill all those processes. grep doesn't know anything except string matches.

Instead, change your task to either accept the process ID (PID) number so there is no question as to which process you want killed, or to kill a process by name, you must decide what to do if there are multiple copies of the same process.

Start by identifying the process by name (really, basename of the executable file used to start the process:

UNIX95= ps -C java

This eliminates grep'ing for grep and finding things that are partial matches. To test this, try something you know is running like:

UNIX95= ps -C sh

Notice that it finds all sh commands but not ksh and even finds the login shells (ie, -sh). NOTE: Type the "UNIX95= ps" exactly as shown--it is a special flag to turn on unique XPG4 behavior. Don't export UNIX95 as it will change the behavior a several commands and library calls.

Now that you have a way to locate just a specific executable by name, you'll need to decide if killing multiple copies is the correct action. If not, show the list and manually pick the PID that is needed. Here is a simple script to kill a process by name:

#!/usr/bin/sh
# Kill a single process by name
# USAGE:

if [ $# -ne 1 ]
then
echo "Usage: $0 process-name"
exit 1
else
MYNAME=$1
fi

# Search for process by basename

MYLIST=$(UNIX95= /usr/bin/ps -C $MYNAME -o pid | grep -v PID )

# None?

if [ -z "$MYLIST" ]
then
echo "No process running called $MYNAME"

# More than 1?

elif [ $(echo $MYLIST | /usr/bin/wc -w) -gt 1 ]
then
echo "More than 1 process called $MYNAME:"
UNIX95= /usr/bin/ps -fC $MYNAME

# Just 1 so kill -15, wait, then check again

else
MYPID=$(echo $MYLIST | awk '{print $1}')
kill $MYPID
sleep 2

# Did it work? If ps succeeds, kill did not work

if /usr/bin/ps -p $MYPID > /dev/null 2>&1
then
echo "$MYNAME (PID=$MYPID) ignoring normal kill"
/usr/bin/ps -fp $MYPID
fi
fi

---

This script tests that you supplied 1 and only 1 process name to kill, then verifies that there is 1 and only 1 process with that name running, and finally, after killing it with -15, verifies that it has disappeared. If not, it shows the process information for manual intervention.


Bill Hassell, sysadmin
James R. Ferguson
Acclaimed Contributor

Re: kill a process

Hi Gerald:

A further comment/contribution:

As Bill explicitly pointed out, and as I implicitly hinted, the 'grep' syntax used in the examples provided would return matches for the expression *anywhere* in the line -- potentially dangerous.

A more rigorous snipet of code to kill a process by name can be seen in the killproc() function of /sbin/init.d/template.

This code isolates the expression to match to the last field returned by 'ps' and ignores its own processes, analogous to using the 'grep -v' in the other examples provided.

Regards!

...JRF...
A. Clay Stephenson
Acclaimed Contributor

Re: kill a process

Hi,

I'll add one more thing to the kill -9 issue.
Before you resort to -9 try using kill -11; it's almost as sure a kill and it does clean up so that file descriptors are closed and shared memory is detached. My ususal sequence if to do a kill -15, kill -1, kill -2, kill -11, and finally any only if I really,really need to kill this process a kill -9.

I typically do something like this in a shell function
kill_pids()
{
DELAY=5
STAT=0
SIGS="15 1 2 11"
while [ $# -ge 1 ]
do
THIS_PID=$1
shift
for SIG in ${SIGS}
do
kill -s 0 ${THIS_PID} >/dev/null 2>&1
STAT=$?
if [ ${STAT} -ne 0 ]
then
break
fi
kill -s ${SIG} ${THIS_PID}
STAT=$?
sleep ${DELAY}
done
done
return ${STAT}
}


Note that you can send a kill -0 pid (or kill -s 0 pid) and check the status to test if the process is valid. If you like you can add 9 to the ${SIGS} and thus also have the 'killer' kill. In practice, kill -11 almost always get 'em.

Regards, Clay
If it ain't broke, I can fix that.