Killing all processes for a user
November 12th, 2006
Lets say you want to kill all processes for a specific user. Maybe they are taking up too many resources or there is an application that runs under the user which needs to be forcefully killed. Here is a simple script to do so:
#!/bin/bash
USER=$1
MYNAME=`basename $0`
if [ ! -n "$USER" ]
then
echo "Usage: $MYNAME username" >&2
exit 1
elif ! egrep "^$USER:" /etc/passwd >/dev/null
then
echo "User $USER does not exist!" >&2
exit 2
fi
PIDS=`ps -U$USER | grep -v PID| awk '{print $1}'`
echo "Killing " `echo $PIDS | wc -w` " processes for user $USER."
for PID in $PIDS
do
kill -9 $PID 2>&1 >/dev/null
done
echo "User $USER has " `ps -U$USER | grep -v PID | wc -l` " processes still running."
In practice:
root@www:~ # ./killUser.sh jerry
Killing 10 processes for user jerry.
User jerry has 0 processes still running.
Seems to work correct? Yes, but it does not work well in all situations. For example, if as you kill the processes, new ones are created the script will not kill those new processes. In WebSphere ND, there is a node agent which starts all the application servers. Sometimes the node agent will keep starting application servers as fast as you can kill both the node agent and the application servers.
Thus, I use an approach like the one below. Wrap a while loop around the for loop which kills everything. The while loop keeps looping until all the processes are dead.
#!/bin/bash
USER=$1
MYNAME=`basename $0`
if [ ! -n "$USER" ]
then
echo "Usage: $MYNAME username" >&2
exit 1
elif ! grep "^$USER:" /etc/passwd >/dev/null
then
echo "User $USER does not exist!" >&2
exit 2
fi
while [ `ps -U$USER | grep -v PID | wc -l` -gt 0 ]
do
PIDS=`ps -U$USER | grep -v PID | awk '{print $1}'`
echo "Killing " `echo $PIDS | wc -w` " processes for user $USER."
for PID in $PIDS
do
kill -9 $PID 2>&1 >/dev/null
done
done
echo "User $USER has 0 processes still running."
Here is how the new script will work with a process that keeps starting new processes:
root@www:~ # ./killUser.sh jerry
Killing 5 processes for user jerry.
Killing 2 processes for user jerry.
User jerry has 0 processes still running.
As you can see, it executes the while loop twice.
UPDATE:
Jon emailed me the following. He is absolutely 100% correct. If the system had two users with user names that start the same, the previous version of the script would kill both user’s processes. I updated the script to use ps -U$USER. Not sure sure why my previous grep statement did not include a space after the user name as that is typically how I account for this. I tried ps -U on three version of Linux, Solaris (10 and 8), and AIX 5.3 and that option was available. If that option is not availabe on your system, the first solution below should work.
Just looking at
http://bashcurescancer.com/killing_all_processes_for _user.html …and noting that in the case of a system with multiple users and
similar usernames, say user1 and user10, `ps -ef | grep “^$USER”` will
match PIDs for user1 *and* user10 (and user11, user100, etc), thus
inadvertently killing many user processes. `ps -ef | grep “^$USER\b”`
ought to fix that. A quick test confirms:# echo user10 | grep “^user1″
user10
# echo user10 | grep “^user1\b”Also note that some versions of ps would let you do this:
ps -Uusername | awk ‘{print $1}’
… which seems inherently safer to me.
November 20th, 2007 at 2:51 am
Easier way :
su – user -c “kill -9 -1″
November 20th, 2007 at 2:52 am
Don’t do that for root..otherwise be prepared to hear a lot from the application folks
January 26th, 2008 at 8:18 am
Nice article.
Su would switch the user as well.
This will be even better
kill -9 `ps -u USERNAME -o “pid=”`
Replace username with actual user.
August 30th, 2009 at 11:47 am
killall -u