This blog is part of a bash tips list I find useful to use on every script -- the whole list can be found here.
When interviewing someone for a job, I almost always ask the question: "how would you kill thousands of processes on a system ?". I won't list all the "interesting" answers/ideas I had but so many people are stuck being able to quickly achieve this task which, first of all, happens in real life (here for example) and, secondly, needs to be fixed very quickly when it happens and you have no time to kill all these process one by one manually after some weird copy and paste technic using a spreadsheet tool :)
To start with, let's create some processes we want to kill (I will create only 5 for the purpose of this blog to keep the output visible); let's create some processes sleeping and doing nothing but a real case scenario would be to kill all the processes of an Oracle instance, processes locking a NFS to be umounted (output of lsof), etc ...:
The first thing to do here is to generate the kill commands; I will use awk for this purpose (with awk, the $2 variable is the second column of the output -- so the PID we want to kill):
Just one thing to keep in mind, remember that with great powers come great responsibility, so be very careful and double check that you grep the good processes you want to kill not to kill too much processes !
Enjoy your new powers !
When interviewing someone for a job, I almost always ask the question: "how would you kill thousands of processes on a system ?". I won't list all the "interesting" answers/ideas I had but so many people are stuck being able to quickly achieve this task which, first of all, happens in real life (here for example) and, secondly, needs to be fixed very quickly when it happens and you have no time to kill all these process one by one manually after some weird copy and paste technic using a spreadsheet tool :)
To start with, let's create some processes we want to kill (I will create only 5 for the purpose of this blog to keep the output visible); let's create some processes sleeping and doing nothing but a real case scenario would be to kill all the processes of an Oracle instance, processes locking a NFS to be umounted (output of lsof), etc ...:
$ for i in {1..5}; do (sleep 3600 &) ; done $ ps -ef | grep sleep | grep -v grep fred 21 1 0 21:28 tty1 00:00:00 sleep 3600 fred 23 1 0 21:28 tty1 00:00:00 sleep 3600 fred 25 1 0 21:28 tty1 00:00:00 sleep 3600 fred 27 1 0 21:28 tty1 00:00:00 sleep 3600 fred 29 1 0 21:28 tty1 00:00:00 sleep 3600 $We now have 5 sleeping processes we want to kill and we know that the second column is the process id (in orange in the above output). We could easily kill them one by one manually as there are only 5 but remember that a real life scenario will be closer to thousands of processes.
The first thing to do here is to generate the kill commands; I will use awk for this purpose (with awk, the $2 variable is the second column of the output -- so the PID we want to kill):
$ ps -ef | grep sleep | grep -v grep | awk '{print "kill "$2}' kill 21 kill 23 kill 25 kill 27 kill 29 $OK great, now that we have all the kill commands, we have to execute them with ... | bash! Indeed, by piping a command into bash (or sh), they will be executed. Let's try that out.
$ ps -ef | grep sleep | grep -v grep | awk '{print "kill "$2}' | bash $ ps -ef | grep sleep | grep -v grep $ <== no more sleep process, they have all been killed !Powerful, right ? indeed it is !
Just one thing to keep in mind, remember that with great powers come great responsibility, so be very careful and double check that you grep the good processes you want to kill not to kill too much processes !
Enjoy your new powers !
Thank you very much for this post. I learned a new thing today.
ReplyDelete1) never, ever do "... | bash"
ReplyDelete2) pgrep sleep; pkill sleep
3) ps -e -o pid= -o cmd= | awk '$2 ~ /sleep/ {print $1}' | xargs kill
4) generally, if you have a complex selection pattern, but get the PIDs in the end, do "... | xargs kill"
cura ut valeas
This comment has been removed by the author.
DeleteCould you please clarify "1) never, ever do "... | bash"" ?
DeleteKill processes works well with xargs but more complex examples may not be that simple if you have many variables in your output. In the oracle world for example, you may have something like:
crsctl xxxx | awk '{
...
many lines here to get what we want
...
}'
And have output variables like the ORACLE_HOME, the ORACLE_SID, the database name, a service name, a target node to start a service to, etc ... so it looks easier to me to generate all the code with awk and execute with | bash.
Regards,