With a little side of applesauce...

Tuesday, January 30, 2007

Bash script to kill processes, kills itself

Here is an interesting problem:


#!/bin/sh

# create the usage message to help new users
usage="
Usage: ${0} [OPTION] [process]

Options:
-h This message
"

while getopts ":ft" OPT
do
case $OPT in
h )
echo "$usage"
exit 1
;;
\?)
echo "$usage"
exit 1;;
esac
done
# remove the flags from $@
shift $((${OPTIND} - 1))

# test to see if there is a list of process names given to killprocess
[ $# -lt 1 ] && echo "$usage" && exit 1

# set PROCNAME to the array of process names that were passed to the killprocess script
PROCNAME="$@"
echo $PROCNAME

# for every process name in PROCNAME, grab all of the processes, and
# kill them... One at a time... ;)
for name in $PROCNAME
do
echo $name
# here, we grep on the process name passed to the script, which
# secretly passes the pid of the script because of the arguments
# that we passed to the script. This kills the script before it
# can move on to the second argument :))
for process in $(ps -ef | grep $name | awk '{print $2}')
do
echo $process
kill $process
done
done

The script above works great for killing processes for a single argument which is passed to the killprocess script. BUT, you get a “terminated” message every time the script has been run, AND, the script is killed before it can process a second argument :P
Here is a version of the script that removes the PID of the killprocess shell script, so that we can kill processes for more than one argument:

#!/bin/sh

# create the usage message to help new users
usage="
Usage: ${0} [OPTION] [process]

Options:
-h This message
"

while getopts ":ft" OPT
do
case $OPT in
h )
echo "$usage"
exit 1
;;
\?)
echo "$usage"
exit 1;;
esac
done
# remove the flags from $@
shift $((${OPTIND} - 1))

# test to see if there is a list of process names given to killprocess
[ $# -lt 1 ] && echo "$usage" && exit 1

# set PROCNAME to the array of process names that were passed to the killprocess script
PROCNAME="$@"
echo $PROCNAME

# for every process name in PROCNAME, grab all of the processes, and
# kill them... One at a time... ;)
for name in $PROCNAME
do
echo $name
# here, we grep on the process name passed to the script, which
# secretly passes the pid of the script because of the arguments
# that we passed to the script. This kills the script before it
# can move on to the second argument :))
#
# for process in $(ps -ef | grep $name | awk '{print $2}')
for process in $(ps -ef | grep $name | grep -v $$ | awk '{print $2}')
do
echo $process
kill $process
done
done

No comments: