我想使用以下方法杀死以下进程
pkill "run_tcp_sender.sh"
Run Code Online (Sandbox Code Playgroud)
或者
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
Run Code Online (Sandbox Code Playgroud)
但它是无用的进程留在那里我的命令有什么问题?
顺便说一句:我可以使用以下命令来实现我想要的
kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')
Run Code Online (Sandbox Code Playgroud)
slm*_*slm 20
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
Run Code Online (Sandbox Code Playgroud)
所以你正在发送信号 #15。如果进程没有响应这个信号,那么你可能需要使用信号 #9, pkill -SIGKILL。
-信号
Run Code Online (Sandbox Code Playgroud)Defines the signal to send to each matched process. Either the numeric or the symbolic signal name can be used. (pkill only.)
OP提到他没有成功pkill -SIGKILL "run_tcp"上班。我们最初认为这个问题与pkill在它完成杀死所有“run_tcp”进程之前可能杀死自己有关。
但是鉴于pkill手册页中的脚注,这很难接受:
正在运行的 pgrep 或 pkill 进程永远不会将自己报告为匹配项。
除此之外,@Gilles 发表的评论基本上是在说同样的事情,pkill只是不会自杀。然后他给了我们一个关于实际发生的事情的重要线索。
这是一个示例,演示了 OP 和我自己缺少的内容:
第 1 步 - 制作 sleepy.bash 脚本
#!/bin/bash
sleep 10000
Run Code Online (Sandbox Code Playgroud)
第 2 步 - 加载一些假睡眠任务
$ for i in `seq 1 5`;do bash sleepy.bash & done
[1] 12703
[2] 12704
[3] 12705
[4] 12706
[5] 12707
Run Code Online (Sandbox Code Playgroud)
第 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
Run Code Online (Sandbox Code Playgroud)
第 4 步 - 尝试使用我的 pkill
$ pkill -SIGTERM sleepy.bash
Run Code Online (Sandbox Code Playgroud)
第 5 步 - 发生了什么?
执行ps上面的命令,我们看到没有任何进程被杀死,就像 OP 问题一样。这是怎么回事?
事实证明,这是我们如何尝试使用pkill. 命令:
pkill -SIGTERM "sleepy.bash"
Run Code Online (Sandbox Code Playgroud)
正在寻找名为"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
Run Code Online (Sandbox Code Playgroud)
现在我们得到了我们想要的效果。有什么区别?我们使用了-fswitch,pkill它pkill在匹配时使用整个命令行路径,而不是仅匹配进程名称。
来自 pkill 手册页
-f The pattern is normally only matched against the process name.
When -f is set, the full command line is used.
Run Code Online (Sandbox Code Playgroud)
杀了,ps
这种方法非常冗长,但也能完成这项工作:
kill -9 $(ps -ef|grep "run_tcp"|grep -v "grep"|awk '{print $2}')
Run Code Online (Sandbox Code Playgroud)
pgrep 带 pkill 和 killall
您可以使用将pgrepPID 列表提供给pkill或killall代替使用。
# pgrep solution
$ pgrep "run_tcp" | pkill -SIGKILL
# killall
killall -SIGKILL -r run_tcp
Run Code Online (Sandbox Code Playgroud)
这与父进程 ID 无关。问题很简单,您正在杀死所有正在运行的进程run_tcp_sender.sh,但您没有这样的进程 — 您感兴趣的进程正在运行bash。
您可以指示pkill在整个命令行上进行匹配:
pkill -f '^bash run_tcp_sender.sh'
Run Code Online (Sandbox Code Playgroud)
另一种方法是杀死所有打开脚本的进程。这可能会造成附带损害,例如对刚刚打开脚本的编辑器。
fuser -k /path/to/run_tcp_sender.sh
Run Code Online (Sandbox Code Playgroud)
只要您不是以 root 身份编辑脚本,仅杀死 root 的进程就可以解决该问题:
kill $(lsof -uroot /path/to/run_tcp_sender.sh)
Run Code Online (Sandbox Code Playgroud)