I often need to kill a process during programming.
The way I do it now is:
[~]$ ps aux | grep 'python csp_build.py'
user 5124 1.0 0.3 214588 13852 pts/4 Sl+ 11:19 0:00 python csp_build.py
user 5373 0.0 0.0 8096 960 pts/6 S+ 11:20 0:00 grep python csp_build.py
[~]$ kill 5124
How can I extract the process id automatically and kill it in the same line?
Like this:
[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>
In
bash, using only the basic tools listed in your question(1), you should be able to do:Details on its workings are as follows:
psgives you the list of all the processes.grepfilters that based on your search string,[p]is a trick to stop you picking up the actualgrepprocess itself.awkjust gives you the second field of each line, which is the PID.$(x)construct means to executexthen take its output and put it on the command line. The output of thatpspipeline inside that construct above is the list of process IDs so you end up with a command likekill 1234 1122 7654.Here’s a transcript showing it in action:
and you can see it terminating all the sleepers.
Explaining the
grep '[p]ython csp_build.py'bit in a bit more detail: when you dosleep 3600 &followed byps -ef | grep sleep, you tend to get two processes withsleepin it, thesleep 3600and thegrep sleep(because they both havesleepin them, that’s not rocket science).However,
ps -ef | grep '[s]leep'won’t create agrepprocess withsleepin it, it instead creates one with the commandgrep '[s]leep'and here’s the tricky bit: thegrepdoesn’t find that one, because it’s looking for the regular expression "any character from the character class[s](which is basically justs) followed byleep.In other words, it’s looking for
sleepbut the grep process isgrep '[s]leep'which doesn’t have the textsleepin it.When I was shown this (by someone here on SO), I immediately started using it because
| grep -v grep; and(1) If you’re not limited to using those basic tools, there’s a nifty
pgrepcommand which will find processes based on certain criteria (assuming you have it available on your system, of course).For example, you can use
pgrep sleepto output the process IDs for allsleepcommands (by default, it matches the process name). If you want to match the entire command line as shown inps, you can do something likepgrep -f 'sleep 9999'.As an aside, it doesn’t list itself if you do
pgrep pgrep, so the tricky filter method shown above is not necessary in this case.You can check that the processes are the ones you’re interested in by using
-ato show the full process names. You can also limit the scope to your own processes (or a specific set of users) with-uor-U. See themanpage forpgrep/pkillfor more options.Once you’re satisfied it will only show the processes you’re interested in, you can then use
pkillwith the same parameters to send a signal to all those processes.