killall给我`没有找到进程`但是ps


17

有人可以向我解释kill和之间的区别killall吗?为什么killall看不到ps显示的内容?

# ps aux |grep db2
root      1123  0.0  0.8 841300 33956 pts/1    Sl   11:48   0:00 db2wdog                                         
db2inst1  1125  0.0  3.5 2879496 143616 pts/1  Sl   11:48   0:02 db2sysc                                        
root      1126  0.0  0.6 579156 27840 pts/1    S    11:48   0:00 db2ckpwd                                        
root      1127  0.0  0.6 579156 27828 pts/1    S    11:48   0:00 db2ckpwd                                        
root      1128  0.0  0.6 579156 27828 pts/1    S    11:48   0:00 db2ckpwd 

# killall db2ckpwd
db2ckpwd: no process found

# kill -9 1126
# kill -9 1127
# kill -9 1128

系统为SuSe 11.3(64位);内核2.6.34-12; procps版本3.2.8;来自PSmisc 22.7的killall; 从GNU coreutils 7.1杀死


切勿使用SIGKILL(-9)终止进程。
vonbrand 2013年

当进程需要终止时该怎么办?
Radek

这是非常非常不得已的手段。
vonbrand

Answers:


19

这在Linux上吗?

有迹象表明,由所使用的命令名称实际上几个微妙的不同版本pskillall等等。

两个主要变体是:1)长命令名,这是您在运行时获得的名称ps u;2)简短的命令名称,即在ps不带任何标志的情况下运行时得到的名称。

如果您的程序是shell脚本或需要解释器的任何内容(例如Python,Java等),则可能会出现最大的差异。

这是一个真正的琐碎脚本,展示了差异。我叫它mycat

#!/bin/sh
cat

运行之后,这是两种不同类型的ps

首先,没有u

$ ps -p 5290
  PID TTY      ... CMD
 5290 pts/6    ... mycat

其次,用u

$ ps u 5290
USER       PID ... COMMAND
mikel     5290 ... /bin/sh /home/mikel/bin/mycat

请注意第二个版本是如何开始的/bin/sh

现在,据我所知,killall实际上是读取/proc/<pid>/stat并抓住括号中的第二个单词作为命令名称,因此这实际上是在运行时需要指定的内容killall。从逻辑上讲,这应该与ps不带u标志的内容相同,但是最好检查一下。

检查事项:

  1. 什么cat /proc/<pid>/stat说的命令名称是什么?
  2. 什么ps -e | grep db2说的命令名称是什么?
  3. 这样做ps -e | grep db2ps au | grep db2表现出同样的命令名称?

笔记

如果您还使用其他ps标志,则可能会更容易使用它ps -o comm来查看简称和ps -o cmd长名称。

您可能还会找到pkill更好的选择。特别是,pkill -f尝试使用完整的命令名称进行匹配,即由ps u或打印的命令名称ps -o cmd


很好的解释。我想你第一次是对的。ps -e |grep db2 gives me 3084吗?00:00:00 db2syscr`和ps aux | grep db2给了我root 3084 0.0 0.6 579292 28304 ? S 13:02 0:00 db2ckpwd。可以对此发表评论。我迷路了。
Radek

我不确定。该程序可能正在更改其名称。你知道它是如何运行的吗?什么ls -l /proc/3084/exe发言权?什么which或者whence或者type找到该文件,然后lstype以查看它是否是一个符号链接或脚本或二进制?
米克尔

ls -l / proc / 3084 / exe给我们lrwxrwxrwx 1 root root 0 Jun 6 16:49 /proc/3084/exe -> /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek

ls -l / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr给我-r-sr-s--- 1 root db2iadm1 147K Feb 1 23:32 /var/lib/db2/db2inst1/sqllib/adm/db2syscr*
Radek

类型给我/ var / lib / db2 / db2inst1 / sqllib / adm / db2syscr/var/lib/db2/db2inst1/sqllib/adm/db2syscr is /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek

6

killall尝试匹配一个进程名称(但是在匹配部分确实不是那么好)。

而且由于“ ps | grep”和“ ps | grep | kill”的工作要好得多,因此有人简化了此过程并创建了pgrep和pkill。阅读该命令,例如“ ps grep”和“ ps kill”,因为该命令先是ps,然后是grep,如果需要则将其杀死。


2

我有一个类似的问题,但/proc/<pid>/stat包含预期的字符串。通过使用strace,我可以看到killall也已访问/proc/<pid>/cmdline

我继续调查使用gdb的情况,发现在我的情况下,将我的命令检查为完整命令(包括在中找到的所有args)失败/proc/<pid>/cmdline。由于文件名的长度超过15个字符(这是killall源中的硬编码值),因此似乎触发了该代码的路径。我没有完全调查我是否可以使其与Killall一起使用。

但是,正如其他评论所提到的,pkill是一个更好的选择,没有相同的问题。

感兴趣的人pkill可以在这里https://github.com/acg/psmisc找到的源代码。


0

在Ubuntu 16系统上,/ proc / pid / stat将包含线程的名称(程序可以通过pthread_setname_np系统调用来使用该名称。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.