pkill 无法终止父进程 ID 为 1 的进程

pkill 无法终止父进程 ID 为 1 的进程

我想使用杀死以下进程

pkill "run_tcp_sender.sh"

或者

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

但进程仍然留在那里是没有用的,我的命令有什么问题?

顺便说一句:我可以使用以下命令来实现我想要的

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

答案1

pkill默认情况下,向进程发送SIGTERM停止信号。以下是您可以向进程发送的信号的列表。您通常可以通过姓名或号码发送他们:

$ 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

因此,您要发送信号#15。如果进程没有响应该信号,那么您可能需要使用信号#9 pkill -SIGKILL

来自pkill 的手册页:

-信号

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

pkill 的问题

OP 提到他未能成功上班pkill -SIGKILL "run_tcp"。我们最初认为该问题与pkill在杀死所有“run_tcp”进程之前可能杀死自己有关。

但考虑到手册页中的脚注,这很难接受pkill

正在运行的 pgrep 或 pkill 进程永远不会将自身报告为匹配项。

除此之外,@Gilles 留下的评论基本上说了同样的话,只是pkill不会自杀。然后他给了我们一个非常重要的线索,让我们知道到底发生了什么。

这是一个示例,演示了 OP 和我自己所缺少的内容:

第 1 步 - 制作 sleepy.bash 脚本

#!/bin/bash

sleep 10000

第 2 步 - 加载一些假睡眠任务

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

步骤 3 - 检查正在运行的任务

$ 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

第 4 步 - 尝试使用我的 pkill

$ pkill -SIGTERM sleepy.bash

第 5 步 - 发生了什么?

从上面执行ps命令,我们看到没有任何进程被终止,就像 OP 问题一样。这是怎么回事?

事实证明,这是我们如何尝试使用pkill.命令:

pkill -SIGTERM "sleepy.bash"

正在寻找一个名为“瞌睡.bash”。嗯,没有任何同名的进程。有一些进程被命名为“bash 瞌睡.bash”尽管。因此,pkill正在寻找要杀死的进程,但没有找到任何进程,然后退出。

因此,如果我们稍微调整pkill我们正在使用的:

$ 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

现在我们得到了我们想要的效果。有什么区别?我们使用了-f开关,pkillpkill匹配时使用整个命令行路径而不是仅使用进程名称。

来自 pkill 手册页

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

替代方法

杀掉,ps

这个方法相当冗长,但也能完成工作:

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

pgrep w/ pkill 和 Killall

您可以使用pgrep将 PID 列表提供给pkill或使用来killall代替。

例子

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

# killall
killall -SIGKILL -r run_tcp

参考

答案2

这与父进程ID无关。问题很简单,您正在终止所有正在运行的进程run_tcp_sender.sh,但您没有这样的进程 - 您感兴趣的进程正在运行bash

您可以指示pkill在整个命令行上进行匹配:

pkill -f '^bash run_tcp_sender.sh'

另一种方法是终止所有打开该脚本的进程。这可能会造成附带损害,例如对刚刚打开脚本的编辑器造成损害。

fuser -k /path/to/run_tcp_sender.sh

只要您不以 root 身份编辑脚本,仅终止 root 进程就可以解决该问题:

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

答案3

下面的命令很简单,对我来说非常完美!上述建议不起作用或效率不高(太复杂)。

kill -9 $(pgrep -f somepattern)

我建议在运行kill命令之前查看哪些进程匹配

pgrep -af somepattern

答案4

尝试用“signal 9”终止进程,我的意思是使用

kill -9 PID

通常不建议使用 signal 9 来杀死数据库引擎

如果进程保留在内存中,则某些 I/O 丢失或进程正在等待 I/O 完成

相关内容