Process

pkill 無法殺死父程序 id 為 1 的程序

  • September 24, 2020

我想使用殺死以下程序

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}')

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命令,我們看到沒有一個程序被殺死,就像 OPs 問題一樣。這是怎麼回事?

事實證明,這是我們如何嘗試使用pkill. 命令:

pkill -SIGTERM "sleepy.bash"

正在尋找一個名為**“sleepy.bash”的程序。好吧,沒有任何同名的程序。不過,有些程序被命名為“bash sleepy.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開關。pkill``pkill

從 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

參考

引用自:https://unix.stackexchange.com/questions/74874