I want to kill all processes that I get by:
ps aux | grep my_pattern
How to do it?
This does not work:
pkill my_pattern
ps -ef | grep 'myProcessName' | grep -v grep | awk '{print $2}' | xargs -r kill -9
What's this code doing?
The ps -ef
produces a list of process id's on the computer visible to this user. The pipe grep filters that down for rows containing that string. The grep -v grep
says don't match on the process itself doing the grepping. The pipe awk print says split the rows on default delimiter whitespace and filter to the second column which is our process id. The pipe xargs spins up a new process to send all those pid's to kill -9
, ending them all.
The above code is bad, dangerous, ugly and hackish for several reasons.
If the code being force-ended is doing any database ops or secure transactions with low probability race conditions, some fraction of a percent of the time, atomicity of that transaction will be wrecked, producing undefined behavior. kill -9 takes no prisoners. If your code is sensitive to this, try replacing the xargs kill
part with a transmitted flag that requests a graceful shutdown, and only if that request is denied, last-resort to kill -9
There's a non zero possibility that you will accidentally end the operating system or caused undefined behavior in an unrelated process, leading to whole system instability because ps -ef
lists every possible process that could exist, and you can't be sure some weird 3rd party library shares your process name, or that in the time between read and execute kill -9, the processid had changed to something else, and now you've accidentally ended some random process you didn't intend to.
But, if you understand the risks and control for them with very unique names, and you're ok with a few dropped transactions or occasional corruption in data, then 99.9% of the time yer gonna be fine. If there's a problem, reboot the computer, make sure there aren't any process collisions. It's because of code like this that makes the tech support script: "Have you tried restarting your computer" a level 5 meme.
If you judge pkill -f PATTERN
a bit too dangerous, I wrote ezkill a bash script that prompt you to choose which processes amongst those that match the PATTERN you want to kill.
it's best and safest to use pgrep -f
with kill
, or just pkill -f
, grep
ing ps
's output can go wrong.
Unlike using ps | grep
with which you need to filter out the grep line by adding | grep -v
or using pattern tricks, pgrep
just won't pick itself by design.
Moreover, should your pattern appear in ps
's UID
/USER
, SDATE
/START
or any other column, you'll get unwanted processes in the output and kill them, pgrep
+pkill
don't suffer from this flaw.
also I found that killall -r
/ -regexp
didn't work with my regular expression.
pkill -f "^python3 path/to/my_script$"
I took Eugen Rieck's answer and worked with it. My code adds the following:
ps ax
includes grep, so I excluded it with grep -Eiv 'grep'
I've created a file, named it killserver
, here it goes:
#!/bin/bash
PROCESS_TO_KILL=bin/node
PROCESS_LIST=`ps ax | grep -Ei ${PROCESS_TO_KILL} | grep -Eiv 'grep' | awk ' { print $1;}'`
KILLED=
for KILLPID in $PROCESS_LIST; do
if [ ! -z $KILLPID ];then
kill -9 $KILLPID
echo "Killed PID ${KILLPID}"
KILLED=yes
fi
done
if [ -z $KILLED ];then
echo "Didn't kill anything"
fi
Results
➜ myapp git:(master) bash killserver
Killed PID 3358
Killed PID 3382
Killed
➜ myapp git:(master) bash killserver
Didn't kill anything
my_pattern
simply a substring of the name, or does it contain any regex special characters? – Sven Marnach