789

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>
Orjanp
  • 10,641
  • 12
  • 36
  • 39
  • 3
    Believe me! :'D The first answer you selected is way more complex than the solution you told you in your answer. I would rather choose your way. – Santosh Kumar Jun 24 '15 at 12:27
  • best way to check if process exists: http://stackoverflow.com/questions/3043978/how-to-check-if-a-process-id-pid-exists – Trevor Boyd Smith Jun 07 '16 at 15:45

31 Answers31

1697

In bash, using only the basic tools listed in your question(1), 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

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 grep process with sleep in it, it instead creates one with the command grep '[s]leep' and here's the tricky bit: the grep doesn't find that one, because it's looking for the regular expression "any character from the character class [s] (which is basically just s) followed by leep.

In other words, it's looking for sleep but the grep process is grep '[s]leep' which doesn't have the text 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 :-)

(1) If you're not limited to using those basic tools, there's a nifty pgrep command which will find processes based on certain criteria (assuming you have it available on your system, of course).

For example, you can use pgrep sleep to output the process IDs for all sleep commands (by default, it matches the process name). If you want to match the entire command line as shown in ps, you can do something like pgrep -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 -a to show the full process names. You can also limit the scope to your own processes (or a specific set of users) with -u or -U. See the man page for pgrep/pkill for more options.

Once you're satisfied it will only show the processes you're interested in, you can then use pkill with the same parameters to send a signal to all those processes.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • First trouble: Your command delete only first process ID. For correct delete all process, should append "| xargs" after awk, this write process ID to single line. Second trouble: This command return error if use simple regexp without macro-chars. In this case, ps command found himself ID, but in running-time kill, ps-process no longer exists. – Xintrea Apr 18 '23 at 11:32
  • @Xintrea, your first comment is wrong, as evidenced by the transcript. The `kill` command will happily accept and kill *multiple* PIDs. Your second statement is right but irrelevant since I never *suggested* using a "simple regexp without macro-chars" (assuming those "macro chars" are the `[p]` bit, which seems to be the case based on the behaviour you give). If I suggest you do A, you can hardly fault me if you decide to do B instead and it doesn't work :-) However, let me know if I've misunderstood your comment, that *may* be the case. – paxdiablo Apr 18 '23 at 16:49
184

if you have pkill,

pkill -f csp_build.py

If you only want to grep against the process name (instead of the full argument list) then leave off -f.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
121

One liner:

ps aux | grep -i csp_build | awk '{print $2}' | xargs sudo kill -9

  • Print out column 2: awk '{print $2}'
  • sudo is optional
  • Run kill -9 5124, kill -9 5373 etc (kill -15 is more graceful but slightly slower)

Bonus:

I also have 2 shortcut functions defined in my .bash_profile (~/.bash_profile is for osx, you have to see what works for your *nix machine).

  1. p keyword
    • lists out all Processes containing keyword
    • usage e.g: p csp_build , p python etc

bash_profile code:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}
  1. ka keyword
    • Kills All processes that have this keyword
    • usage e.g: ka csp_build , ka python etc
    • optional kill level e.g: ka csp_build 15, ka python 9

bash_profile code:

# KILL ALL
function ka(){

    cnt=$( p $1 | wc -l)  # total count of processes found
    klevel=${2:-15}       # kill level, defaults to 15 if argument 2 is empty

    echo -e "\nSearching for '$1' -- Found" $cnt "Running Processes .. "
    p $1

    echo -e '\nTerminating' $cnt 'processes .. '

    ps aux  |  grep -i $1 |  grep -v grep   | awk '{print $2}' | xargs sudo kill -klevel
    echo -e "Done!\n"

    echo "Running search again:"
    p "$1"
    echo -e "\n"
}
a20
  • 5,495
  • 2
  • 30
  • 27
23
killall -r regexp

-r, --regexp

Interpret process name pattern as an extended regular expression.

Nazik
  • 8,696
  • 27
  • 77
  • 123
Miron Yanovskiy
  • 640
  • 7
  • 12
  • why is this not in the top?! It does exactly what is asked for with only two-three words... – FullStack Alex Aug 10 '22 at 01:20
  • How to do a dry run test? Possible answer: [`SIGCONT` means "continue"](https://en.wikipedia.org/wiki/Signal_(IPC)) which should be pretty harmless to send. I used `killall -s SIGCONT -r 'RegexHere'` for testing. It doesn't give the list of processes, but it does work for doing a sort of "dry run" of the command. I guess a similar method would be to just use your regex with `ps aux | grep 'RegexHere'`... – rinogo Feb 14 '23 at 00:52
  • 1
    Also, as for the question of "why is this not in the top?" As far as I can tell, this only seems to operate on the actual command name, *not including all of the command-line parameters*. – rinogo Feb 14 '23 at 01:00
19

This will return the pid only

pgrep -f 'process_name'

So to kill any process in one line:

kill -9 $(pgrep -f 'process_name')

or, if you know the exact name of the process you can also try pidof:

kill -9 $(pidof 'process_name')

But, if you do not know the exact name of the process, pgrep would be better.

If there is multiple process running with the same name, and you want to kill the first one then:

kill -9 $(pgrep -f 'process_name' | head -1)

Also to note that, if you are worried about case sensitivity then you can add -i option just like in grep. For example:

kill -9 $(pgrep -fi chrome)

More info about signals and pgrep at man 7 signal or man signal and man pgrep

Rakib Fiha
  • 473
  • 8
  • 13
17

Try using

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill
Sergey Kishenin
  • 5,099
  • 3
  • 30
  • 50
Rahul
  • 1,866
  • 17
  • 32
  • 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 Aug 18 '10 at 10:27
  • 3
    `ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs kill` worked for me. thanx – Govinnage Rasika Perera Apr 26 '15 at 05:45
  • 1
    Remember, kids, Awk can do everything `grep` can, and most of it simply and elegantly. The trivial case of `grep x y | awk '{ z }'` is always better written `awk '/x/ { z }' y` -- see also [useless use of `grep`](http://www.iki.fi/era/unix/award.html#grep). – tripleee Jan 24 '17 at 08:15
13

You may use only pkill '^python*' for regex process killing.

If you want to see what you gonna kill or find before killing just use pgrep -l '^python*' where -l outputs also name of the process. If you don't want to use pkill, use just:

pgrep '^python*' | xargs kill

NGix
  • 2,542
  • 8
  • 28
  • 39
11

Use pgrep - available on many platforms:

kill -9 `pgrep -f cps_build`

pgrep -f will return all PIDs with coincidence "cps_build"

vr286
  • 826
  • 7
  • 6
  • 2
    If you have `pgrep`, you will also have `pkill`. As always, [don't use `kill -9`](http://www.iki.fi/era/unix/award.html#kill) unless you know why `kill -15` (the default) or `kill -2` will not work. – tripleee Jul 27 '16 at 09:39
  • This looks like a worse paraphrase of [@nathanael's answer](http://stackoverflow.com/a/31927202/874188) which omits the misdirected `-9` and uses the proper modern command substitution syntax. Upvote that instead; though of course, the [`pkill` answer](http://stackoverflow.com/a/3511301/874188) is better still. – tripleee Jul 27 '16 at 09:40
  • @tripleee In this case kill -9 is exactly what I want - terminate all offenders with extreme prejudice. Moreover, I've used kill -9 for many years with no problems. In my opinion, there will always be a camp of purists vs a camp of get-things-done realists, and I belong to the latter (in this matter). – a20 Jan 24 '17 at 04:06
  • Did you miss the "unless you know why" part? I'm all for getting things done, but this is one of the common ways of shooting yourself in the foot until you understand what the `-9` actually means. – tripleee Jan 24 '17 at 04:24
  • @tripleee hey tripleee, I recently found that you are right, kill -15 is a better choice because it gives the app chance to kill itself gracefully. I've changed my code accordingly: http://stackoverflow.com/a/30486159/163382 – a20 Mar 15 '17 at 05:31
  • this saved my life – DJ_Stuffy_K Apr 24 '21 at 01:29
8

The solution would be filtering the processes with exact pattern , parse the pid, and construct an argument list for executing kill processes:

ps -ef  | grep -e <serviceNameA> -e <serviceNameB> -e <serviceNameC> |
awk '{print $2}' | xargs sudo kill -9

Explanation from documenation:

ps utility displays a header line, followed by lines containing information about all of your processes that have controlling terminals.

-e Display information about other users' processes, including those

-f Display the uid, pid, parent pid, recent CPU usage, process start

The grep utility searches any given input files, selecting lines that

-e pattern, --regexp=pattern Specify a pattern used during the search of the input: an input line is selected if it matches any of the specified patterns. This option is most useful when multiple -e options are used to specify multiple patterns, or when a pattern begins with a dash (`-').

xargs - construct argument list(s) and execute utility

kill - terminate or signal a process

number 9 signal - KILL (non-catchable, non-ignorable kill)

Example:

ps -ef  | grep -e node -e loggerUploadService.sh -e applicationService.js |
awk '{print $2}' | xargs sudo kill -9
avivamg
  • 12,197
  • 3
  • 67
  • 61
  • 1
    This is a superior (less complicated) answer and great description/explanation ... – Zak Jul 22 '21 at 22:32
7

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
  • 4,246
  • 3
  • 33
  • 57
  • Don't you will kill both process 5124 and 5373 then? I guess this is not a problem. – Orjanp Aug 18 '10 at 09:48
  • 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 Aug 18 '10 at 10:02
  • Tested with a slightly modified command. But it did not kill the process, only printed kill . ps auxf | grep '[p]ython csp_build.py' | awk '{print "kill " $2}' – Orjanp Aug 18 '10 at 10:07
  • Only needed to swap the print "kill " $2 statement with a system ("kill " $2). Then it works. :) – Orjanp Aug 18 '10 at 10:24
6

My task was kill everything matching regexp that is placed in specific directory (after selenium tests not everything got stop). This worked for me:

for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done
Serge
  • 1,947
  • 3
  • 26
  • 48
  • The `-9` option of `kill` is perhaps too aggresive. It doesn't let them to free their resources. – Birei Jan 08 '14 at 22:54
  • Nice! The only one that consider the fact that there might be more than one matching process! One small note: perhaps you may want to add a "grep -v grep" or something like that to the pipes, to ensure that the grep process itself doesn't show up in your process list. – Brad Parks Jan 30 '14 at 18:17
  • `kill` accepts multiple processes so the loop is basically useless; and as noted elsewhere on this page, you should not be using `kill -9` unless you *know* that the process won't respond to just `kill`. – tripleee Feb 15 '18 at 12:46
  • remove -9 is not a big deal, why downvote. You'd better edited the answer. – Serge Feb 15 '18 at 15:45
5

To kill process by keyword midori, for example:

kill -SIGTERM $(pgrep -i midori)

a20
  • 5,495
  • 2
  • 30
  • 27
l3v1ath4n
  • 59
  • 1
  • 1
5

Lots of good answers here - I used the answer accepted by the OP. Just adding a small caveat note about pkill and pgrep. As you might see from their manual pages, on your OS, some OS's have a 15-character limit on the process name. The -f option gets around that on my OS, but I was in trouble until I found that option!

Neil Gatenby
  • 419
  • 6
  • 21
4
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15
Vijay
  • 65,327
  • 90
  • 227
  • 319
3

Give -f to pkill

pkill -f /usr/local/bin/fritzcap.py

exact path of .py file is

# ps ax | grep fritzcap.py
 3076 pts/1    Sl     0:00 python -u /usr/local/bin/fritzcap.py -c -d -m
Robert1968
  • 189
  • 1
  • 10
3

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
  • 10,958
  • 2
  • 46
  • 71
2

I started using something like this:

kill $(pgrep 'python csp_build.py')
N7L
  • 109
  • 1
  • 3
1

You don't need the user switch for ps.

kill `ps ax | grep 'python csp_build.py' | awk '{print $1}'`
Alex V
  • 18,176
  • 5
  • 36
  • 35
1

In some cases, I'd like kill processes simutaneously like this way:

➜  ~  sleep 1000 &
[1] 25410
➜  ~  sleep 1000 &
[2] 25415
➜  ~  sleep 1000 &
[3] 25421
➜  ~  pidof sleep
25421 25415 25410
➜  ~  kill `pidof sleep`
[2]  - 25415 terminated  sleep 1000                                                             
[1]  - 25410 terminated  sleep 1000
[3]  + 25421 terminated  sleep 1000

But, I think it is a little bit inappropriate in your case.(May be there are running python a, python b, python x...in the background.)

kashu.org
  • 11
  • 1
1

Find and kill all the processes in one line in bash.

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
  • ps -ef | grep '<exe_name>' - Gives the list of running process details (uname, pid, etc ) which matches the pattern. Output list includes this grep command also which searches it. Now for killing we need to ignore this grep command process.
  • ps -ef | grep '<exec_name>' | grep -v 'grep' - Adding another grep with -v 'grep' removes the current grep process.
  • Then using awk get the process id alone.
  • Then keep this command inside $(...) and pass it to kill command, to kill all process.
rashok
  • 12,790
  • 16
  • 88
  • 100
1

If pkill -f csp_build.py doesn't kill the process you can add -9 to send a kill signall which will not be ignored. i.e. pkill -9 -f csp_build.py

Yonas Kassa
  • 3,362
  • 1
  • 18
  • 27
1

Using -C flag of ps command

-C cmdlist
     Select by command name.  This selects the processes whose
     executable name is given in cmdlist.

1st case, simple command

So if you run your script by standard shebang and calling them by his name:

/path/to/csp_build.py

You may find them whith

ps -C csp_build.py

So

kill $(ps -C csp_build.py ho pid)

may be enough.

2nd case, search for cmd

A little more strong, but still a lot quicker than most other answer in this SO question...

If you don't know ho this is run, or if you run them by

python csp_build.py
python3 csp_build.py
python /path/to/csp_build.py

You may find them by running:

ps -C python,python3,csp_build.py who pid,cmd | grep csp_build.py

Then using sed:

kill $(ps -C python,python3,csp_build.py who pid,cmd |
    sed -ne '/csp_build.py/s/^ *\([0-9]\+\) .*$/\1/p')
F. Hauri - Give Up GitHub
  • 64,122
  • 17
  • 116
  • 137
1

Based on https://stackoverflow.com/a/3510879/15603477 answer. Minor optimization.

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

By using tr -s ' ' to squeeze multi whitespaces (if have) to 1 white space.

In case you encountered Operation not permitted follow this>> https://unix.stackexchange.com/questions/89316/how-to-kill-a-process-that-says-operation-not-permitted-when-attempted

jian
  • 4,119
  • 1
  • 17
  • 32
1
pkill -f 'PATTERN'

Will kill all the processes that the pattern PATTERN matches. With the -f option, the whole command line (i.e. including arguments) will be taken into account. Without the -f option, only the command name will be taken into account.

Xiaobing Mi
  • 102
  • 5
0

Kill our own processes started from a common PPID is quite frequently, pkill associated to the –P flag is a winner for me. Using @ghostdog74 example :

# sleep 30 &                                                                                                      
[1] 68849
# sleep 30 &
[2] 68879
# sleep 30 &
[3] 68897
# sleep 30 &
[4] 68900
# pkill -P $$                                                                                                         
[1]   Terminated              sleep 30
[2]   Terminated              sleep 30
[3]-  Terminated              sleep 30
[4]+  Terminated              sleep 30
Juan Diego Godoy Robles
  • 14,447
  • 2
  • 38
  • 52
  • I can't even tell what you are trying to do here. More text and maybe it will make sense. – Al Ro Mar 14 '22 at 00:06
0

I use this to kill Firefox when it's being script slammed and cpu bashing :) Replace 'Firefox' with the app you want to die. I'm on the Bash shell - OS X 10.9.3 Darwin.

kill -Hup $(ps ux | grep Firefox | awk 'NR == 1 {next} {print $2}' | uniq | sort)

mrhassell
  • 125
  • 2
  • Replacing `grep Firefox | awk 'NR == 1 { next } ...'` with `awk 'NR == 1 || $11 !~ /Firefox/ { next } ...'` not only saves a process, but also improves the precision. It's not hard to get rid of `sort | uniq` in pure Awk either (whereas of course `uniq | sort` is just wrong -- it will miss any duplicates which are not adjacent, and hide the error by needlessly sorting the *output* of `uniq`). – tripleee Feb 15 '18 at 12:44
0

I use gkill processname, where gkill is the following script:

cnt=`ps aux|grep $1| grep -v "grep" -c`
if [ "$cnt" -gt 0 ]
then
    echo "Found $cnt processes - killing them"
    ps aux|grep $1| grep -v "grep"| awk '{print $2}'| xargs kill
else
    echo "No processes found"
fi

NOTE: it will NOT kill processes that have "grep" in their command lines.

Kostyantyn
  • 5,041
  • 3
  • 34
  • 30
  • 1
    Like the many, many other reinventions of the yak shed, this is riddled with [useless use of `grep`](http://www.iki.fi/era/unix/award.html#grep) and other common shell script antipatterns. – tripleee Jul 27 '16 at 09:43
0

if you wanna do it mostly within awk, try

  for i in $(jot 5); do 
 (python3 -c 'import sys; [ print(_) for _ in sys.stdin ]' ) & done; 
  
  sleep 1; ps aux | {m,g}awk '

       /[p]ython/ { 
              _=(_)" "$2 
       } END { 
           system("echo \47 kill "(_)" \47")
           system(      "kill -9 " _) }'


[302] 14236
[303] 14237
[304] 14238
[305] 14239
[306] 14240
[303]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[305]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[304]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[302]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[306]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
 
 kill  14239 14237 14236 14240 14238 
 
[305]    killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[303]    killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[306]  + killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[304]  - killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[302]  + killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
RARE Kpop Manifesto
  • 2,453
  • 3
  • 11
-1

The following command will come handy:

kill $(ps -elf | grep <process_regex>| awk {'print $4'})

eg., ps -elf | grep top

    0 T ubuntu    6558  6535  0  80   0 -  4001 signal 11:32 pts/1    00:00:00 top
    0 S ubuntu    6562  6535  0  80   0 -  2939 pipe_w 11:33 pts/1    00:00:00 grep --color=auto top

kill -$(ps -elf | grep top| awk {'print $4'})

    -bash: kill: (6572) - No such process
    [1]+  Killed                  top

If the process is still stuck, use "-9" extension to hardkill, as follows:

kill -9 $(ps -elf | grep top| awk {'print $4'})

Hope that helps...!

Akshay Shah
  • 323
  • 2
  • 16
-1

I don't like killing things based purely on a blind result from grep - what if I mistakenly match more than desired?

I know this is going to get downvoted by command line purists, but I prefer an interactive filter for this case, such as pick (apt-get install pick). With this kind of tool the filtered result is displayed as you type, so you can see exactly what will get killed when you hit enter.

Thus the one-liner would become

function killpick { ps ax | pick -q "$1" | awk  '{print $1}' | xargs kill -9; }

killpick by itself gives a chooser with incremental filtering, with the optional argument giving a starting string for the filter.

Al Ro
  • 466
  • 2
  • 11
-1

For basic bash versions

kill $(pidof <my_process>)

Oras
  • 120
  • 1
  • 9