views:

136

answers:

6

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>
+1  A: 

you can do it with awk and backtics

ps auxf |grep 'python csp_build.py'|`awk '{ print "kill " $2 }'`

$2 in awk prints column 2, and the backtics runs the statement that's printed.

But a much cleaner solution would be for the python process to store it's process id in /var/run and then you can simply read that file and kill it.

Alexander Kjäll
Don't you will kill both process 5124 and 5373 then? I guess this is not a problem.
Orjanp
it shouldn't be a problem, but you can always add another grep to exclude the grep process: "grep -v grep" between grep and awk
Alexander Kjäll
Tested with a slightly modified command. But it did not kill the process, only printed kill <pid>. ps auxf | grep '[p]ython csp_build.py' | awk '{print "kill " $2}'
Orjanp
Only needed to swap the print "kill " $2 statement with a system ("kill " $2). Then it works. :)
Orjanp
+1  A: 

A method using only awk (and ps):

ps aux | awk '$11" "$12 == "python csp_build.py" { system("kill " $2) }'

By using string equality testing I prevent matching this process itself.

schot
For some reason I don't get a hit on "python csp_build.py". But "python" alone hits.
Orjanp
@Orjanp Yes, stupid oversight on my part, see new version.
schot
Yes, there is is. :) Thanks.
Orjanp
+6  A: 

In bash, you should be able to do:

kill $(ps aux | grep '[p]ython csp_build.py' | awk '{print $2}')

Details on its workings are as follows:

  • The ps gives you the list of all the processes.
  • The grep filters that based on your search string, [p] is a trick to stop you picking up the actual grep process itself.
  • The awk just gives you the second field of each line, which is the PID.
  • The $(x) construct means to execute x then take its output and put it on the command line. The output of that ps pipeline inside that construct above is the list of process IDs so you end up with a command like kill 1234 1122 7654.

Here's a transcript showing it in action:

pax> sleep 3600 &
[1] 2225
pax> sleep 3600 &
[2] 2226
pax> sleep 3600 &
[3] 2227
pax> sleep 3600 &
[4] 2228
pax> sleep 3600 &
[5] 2229
pax> kill $(ps aux | grep '[s]leep' | awk '{print $2}')
[5]+  Terminated              sleep 3600
[1]   Terminated              sleep 3600
[2]   Terminated              sleep 3600
[3]-  Terminated              sleep 3600
[4]+  Terminated              sleep 3600
pax> _

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 do sleep 3600 & followed by ps -ef | grep sleep, you tend to get two processes with sleep in it, the sleep 3600 and the grep sleep (because they both have sleep in them, that's not rocket science).

However, ps -ef | grep '[s]leep' won't create a process with sleep in it, it instead creates grep '[s]leep' and here's the tricky bit: the grep doesn't find it because it's looking for the regular expression "any character from the character class [s] (which is s) followed by leep.

In other words, it's looking for sleep but the grep process is grep '[s]leep' which doesn't have sleep in it.

When I was shown this (by someone here on SO), I immediately started using it because

  • it's one less process than adding | grep -v grep; and
  • it's elegant and sneaky, a rare combination :-)
paxdiablo
`[p]` is nice :-D
Pavel Shved
I can't claim total credit for that, I actually learnt it here on SO. I'd been using `| grep -v grep` up until I learnt that one.
paxdiablo
Works like a charm. :) Thanks.
Orjanp
@paxdiablo, can you provide a link for that? I'm baffled why it works.
glenn jackman
@glenn, I've tried to clarify it a bit. Hope that helps.
paxdiablo
@paxdiablo, sorry I wasn't clear: I was referring specifically to the `[p]` "trick". How does that filter out the grep process?
glenn jackman
@glenn, see the addendum.
paxdiablo
+1  A: 

try using

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill

Rahul
Had to change it a bit. This worked. Thanks. :) ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 5 | xargs kill
Orjanp
+2  A: 
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15
Vijay Sarathi
Can't +1 due to daily limit, but using `ps` with `-o` option is worth using.
Pavel Shved
ps don't give me much.[~]$ ps PID TTY TIME CMD 6365 pts/6 00:00:00 ps29112 pts/6 00:00:00 bash
Orjanp
A: 

if you have pkill,

pkill csp_build.py
ghostdog74
Nothing happened when I tested this.
Orjanp
use pgrep first to verify you have grepped the correct process. then use pkill again on the correct pattern.
ghostdog74