Search and Kill Processes With One Line [Command Line]
Alright, this may seem a bit long winded. I promise though, it really is just one line! Also, yes there are probably tens of different ways to do this. Some maybe even better than what I outlined below. If that’s the case, definitely give me a shout in the comments below.
We’ve all written a python, bash, or php script to process or manipulate a ton of data. Maybe do some video transcoding, process backups, or generate cat memes all day long on a cron and email everyone on your mailing list. At some point you’re going to screw up and you’ll have hundreds of runaway processes going on your system either with a bug or some other fatal situation that may cause resource abuse. What’s worse is that these scripts might be running in the background on an infinite loop and you don’t have a real easy way of terminating them.
Let’s say you have a bunch of process like this and you want to terminate every instance of kittens.py.
sajan@myserver~: # ps aux USER PID TT STAT TIME COMMAND sajan 34873 2 Is 0:00.00 /bin/python kittens.py sajan 34874 2 Is 0:00.00 /bin/python kittens.py sajan 34875 2 Is 0:00.00 /bin/python kittens.py sajan 34876 2 Is 0:00.00 /bin/python kittens.py ..... ..... [other important system processes] ..... ..... sajan 34919 2 Is 0:00.00 /bin/python kittens.py sajan 34820 2 Is 0:00.00 /bin/python kittens.py sajan 34821 2 Is 0:00.00 /bin/python kittens.py
You could use the kill command to kill each process individually using the process id.
kill 34873 kill 34874 kill 34875 .... kill 34921
Let’s be real though, this is Linux; There has to be an easier way.
We’re not going to sit here and selectively kill each and every process by hand. No.
What we want to do is have our system look for any and all processes that satisfy a regular expression, get the process id, and kill it all in one go. Don’t worry, you don’t need to be a regular expression guru, I don’t think those people even exist. All you need is this one line.
kill $(ps aux | grep '[k]ittens.py' | awk '{print $2}')
This command will go through all your processes, find all the kittens.py, and kill them. Alright, that was a terrible joke and I love kittens. Nobody here condones killing anything (except for bad processes).
Let’s break this down. There are four commands being used here.
- ps aux – This is what’s going to give us a nice line by line list of all of our running processes.
- grep – This is going to filter that list of processes and only show us lines that we want. In this case, we want only lines with ‘kittens.py’.
- awk – Each of the filtered lines after the grep will have several pieces of information, we’re only interested in the second field. So we print that second field which is the process id.
- kill – That process id then gets printed as an argument to our normal kill command which will kill it.
Done deal.
Wait! Why did we put the first letter of our search term inside a pair of brackets? Great question! This is a small little tip a friend of mine laid on me a while back. When we do the grep, it in itself is actually a process. If I show you the above ps aux output with our grep, it’ll look something like this.
sajan@myserver~: # ps aux USER PID TT STAT TIME COMMAND sajan 1337 2 Is 0:00.00 /bin/grep kittens.py sajan 34873 2 Is 0:00.00 /bin/python kittens.py sajan 34874 2 Is 0:00.00 /bin/python kittens.py sajan 34875 2 Is 0:00.00 /bin/python kittens.py sajan 34876 2 Is 0:00.00 /bin/python kittens.py ..... ..... ..... sajan 34919 2 Is 0:00.00 /bin/python kittens.py sajan 34820 2 Is 0:00.00 /bin/python kittens.py sajan 34821 2 Is 0:00.00 /bin/python kittens.py
You see how the grep command is listed in the output. Since it has the ‘kittens.py’ in the line, it will actually be returned just like the ones we want to kill and kill the grep as well. Which we don’t want to do. So instead, in our grep command we use a regular expression. A simple one.
[k] is the same as just 'k' during the regular expression evaluation.
With this regular expression, by putting the first letter in brackets, it will still search for our kittens.py, but the process name will be something like this.
1337 2 Is 0:00.00 /bin/grep [k]ittens.py
Meaning the grep process won’t be killed as [k]ittens.py is not the same as kittens.py during the search.
A Note About the PS Command
In my example above, we used ps aux everywhere and had awk print the second field to get the process id to kill. However, if you use different arguments for ps, the process id might not be in the second field. So you’d have to adjust that.
If we do ps aux like in my example above, each line looks something like this.
sajan 34875 2 Is 0:00.00 /bin/python kittens.py
You’ll see the process id is the second field, which is why that’s what we printed with awk for our kill command.
If we change this to ps ax, the output changes to the following because we don’t get the user.
34875 2 Is 0:00.00 /bin/python kittens.py
In this case the process id is printed as the first field. So we’d need to change our line to reflect that. Rather than printing the second field like in the example above, we’d print the first.
kill $(ps aux | grep '[k]ittens.py' | awk '{print $1}')
Hopefully having spent 5 minutes reading this saves you 10 seconds somewhere down the road.