15

I want to kill the following processes using

pkill "run_tcp_sender.sh"

or

pkill -SIGKILL  "run_tcp_sender.sh"


    root     14320     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14323     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14325     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14327     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14328     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22
    root     14330     1  0  2012 ?        00:00:00 bash run_tcp_sender.sh 138.96.116.22

but it is useless the processes remain there what is wrong with my command?

BTW: I can use the following command to achieve what I want

kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')
2
  • 1
    What state are the processes in when they can't be killed? "State D" processes generally have to come out of state D (when their I/O finishes) before they look at their signals and state Z processes can't be killed no matter what (short of the parent reaping the child or the admin rebooting the machine). My thinking is that using another command might be just you doing something else for a while and the processes change state on you.
    – Bratchley
    Commented May 6, 2013 at 15:07
  • 2
    Does pgrep "run_tcp_sender.sh" return the list of processes you want to kill, or does it just return an empty list because the processes are all listed as bash run_tcp_sender.sh ...? Commented May 6, 2013 at 17:22

4 Answers 4

24

pkill by default sends the SIGTERM signal to processes to stop. Here's a list of the signals you can send a process. You can send them by name or number typically:

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

So you're sending signal # 15. If the processes are not responding to this signal then you may need to use signal #9, pkill -SIGKILL.

From the man page of pkill:

-signal

  Defines the signal to send to each matched process.  Either the
  numeric  or  the symbolic signal name can be used.  (pkill only.)

Issues with pkill

The OP mentioned that he was unsuccessful in getting pkill -SIGKILL "run_tcp" to work. We initially thought that the issue had to do with pkill potentially killing itself before it had finished killing all the "run_tcp" processes.

But that was hard to accept given a foot note in the pkill man page:

The running pgrep or pkill process will never report itself as a match.

In addition to that, @Gilles left a comment basically saying the same thing, that pkill just does not kill itself. Then he gave us a pretty big clue as to what was actually going on.

Here's an example that demonstrates what the OP and myself were missing:

step 1 - make a sleepy.bash script

#!/bin/bash

sleep 10000

step 2 - load up some fake sleep tasks

$ for i in `seq 1 5`;do bash sleepy.bash & done
[1] 12703
[2] 12704
[3] 12705
[4] 12706
[5] 12707

step 3 - check the running tasks

$ ps -eaf|egrep "sleep 10000|sleepy"
saml     12703 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12704 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12705 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12706 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12707 29636  0 21:48 pts/16   00:00:00 bash sleepy.bash
saml     12708 12704  0 21:48 pts/16   00:00:00 sleep 10000
saml     12709 12707  0 21:48 pts/16   00:00:00 sleep 10000
saml     12710 12705  0 21:48 pts/16   00:00:00 sleep 10000
saml     12711 12703  0 21:48 pts/16   00:00:00 sleep 10000
saml     12712 12706  0 21:48 pts/16   00:00:00 sleep 10000

step 4 - try using my pkill

$ pkill -SIGTERM sleepy.bash

step 5 - what happened?

Doing the ps command from above, we see that none of the processes were killed, just like the OPs issue. What's going on?

Turns out this is an issue in how we were attempting to make use of pkill. The command:

pkill -SIGTERM "sleepy.bash"

was looking for a process by the name of "sleepy.bash". Well there aren't any processes by that name. There's processes that are named "bash sleepy.bash" though. So pkill was looking for processes to kill and not finding any and then exiting.

So if we slightly adjust the pkill we're using to this:

$ pkill -SIGTERM -f "sleepy.bash"
[1]   Terminated              bash sleepy.bash
[2]   Terminated              bash sleepy.bash
[3]   Terminated              bash sleepy.bash
[4]-  Terminated              bash sleepy.bash
[5]+  Terminated              bash sleepy.bash

Now we get the effect we were looking for. What the difference? We made use of the -f switch to pkill which makes pkill use the entire command line path when matching vs. just the process name.

from pkill man page

-f      The pattern is normally only matched against the process name.  
        When  -f  is  set, the full command line is used.

Alternative methods

kill, ps

This method is pretty verbose but does the job as well:

kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')

pgrep w/ pkill & killall

You can use either pgrep to feed a list of PIDs to pkill or make use of killall instead.

Examples

# pgrep solution
$ pgrep "run_tcp" | pkill -SIGKILL

# killall
killall -SIGKILL -r run_tcp

References

6
  • 1
    why SIGTERM doesn't function here?
    – misteryes
    Commented May 6, 2013 at 14:29
  • Not sure, that signals the application to shut itself down, but it isn't responding. The SIGKILL, is the OS destroying the process, which is a little heavy handed to use all the time. Better to let the application close itself if it can.
    – slm
    Commented May 6, 2013 at 14:32
  • pkill -SIGKILL is useless again! I can only use kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}') for killing, strange! do you know why? thanks
    – misteryes
    Commented May 6, 2013 at 14:53
  • No, pkill isn't killing itself, and no, it isn't a matter of which signal is sent. It isn't sending any signal because there's no process by that name. Commented May 7, 2013 at 1:19
  • @slm See my answer Commented May 7, 2013 at 1:31
7

This is unrelated to the parent process ID. The problem is simply that you are killing all the processes running run_tcp_sender.sh, but you have no such processes — the processes you're interested in are running bash.

You can instruct pkill to match on the whole command line:

pkill -f '^bash run_tcp_sender.sh'

Another approach would be to kill all the processes that have the script open. That could make collateral damage, e.g. to an editor that was just opening the script.

fuser -k /path/to/run_tcp_sender.sh

As long as you aren't editing the script as root, killing only root's processes would solve that issue:

kill $(lsof -uroot /path/to/run_tcp_sender.sh)
1

Below command is easy and worked perfect for me! The above suggestions didn't work or not efficient (too complicated).

kill -9 $(pgrep -f somepattern)

I recommend to see which processes match before running kill command

pgrep -af somepattern
5
  • Is there a reason why you wouldn't use pkill -f to kill the matching processes, and why you rather introduce a race condition by first calling pgrep -f and then kill?
    – Kusalananda
    Commented Sep 24, 2020 at 18:06
  • pkill just sends sigterm and in my case, it did not kill any of my processes. pkill -SIGKILL also did not work. pgrep -f returns the pid of matching processes and as I stated, this worked perfectly while the others did not.
    – ibilgen
    Commented Sep 24, 2020 at 20:56
  • You will notice that pkill also has the -f option which makes it match the pattern against the full command line, just like pgrep -f does. The difference being that pkill also sends a signal to the matching processes. With pkill -f -SIGKILL pattern you therefore send the KILL signal to any process whose command line matches pattern.
    – Kusalananda
    Commented Sep 24, 2020 at 22:45
  • 1
    I tried "pkill -f -SIGKILL pattern" but didn't kill my processes but "kill -9 $(pgrep -f somepattern)" killed all of them.
    – ibilgen
    Commented Oct 30, 2020 at 22:03
  • pkill -f -SIGKILL pattern fails miserably. it even reports Killed when pattern is a running process or not even a running process. what?!?! the other methods, like this answer, works. something is not right with pkill Commented Jul 9, 2021 at 16:25
0

Try to kill process with "signal 9" , i mean use

kill -9 PID

normally signal 9 is not recommended for killing databases engine

if process remains in memory, some i/o lost or process is waiting for i/o completion

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .