使用一个命令杀死正在运行的进程的许多实例


75

假设我有一千个或更多实例在运行任何进程(例如vi)。我如何在一击/一线命令/一个命令中杀死它们?


3
目前尚不清楚您打算使用哪种系统。例如,在Linux上,我使用pkillfrom procps软件包。
猎鹿人2012年

这个问题是从一般角度提出的。我只知道两个进程,例如killall和通过awk / sed。但是我想知道是否还有其他方法可以实现这一目标。如果在不同的系统中做的不同,那么我想知道在哪个系统中。谷歌非常麻烦,相反,我想到了与所有有经验的人讨论。
黑暗骑士

Answers:


97

好老的怎么了,

for pid in $(ps -ef | grep "some search" | awk '{print $2}'); do kill -9 $pid; done

有多种方法可以提高效率,

for pid in $(ps -ef | awk '/some search/ {print $2}'); do kill -9 $pid; done

和其他变体,但从根本上讲,它一直对我有用。


1
投上一票,只知道第一个变体。第二个看起来效率更高,谢谢。
黑暗骑士

5
@TheDarkKnight这种方法的问题是,您常常会杀死更多的东西。编写可靠的“某些搜索”非常棘手。在Linux下,请使用pkill,它可以处理大多数细节。
吉尔斯2012年

我不确定这是否很棘手,如果您追求的是特定的二进制文件,那么它可能会非常可靠。echo kill -9 $pid无论如何,我总是将它作为第一篇,所以我知道自己会得到什么。我不确定AIX是否有pkillUNIX,这是我的基本面。而且真的很糟糕以至于无法投票-奇怪。
EightBitTony

1
除非绝对必要,否则应发送进程SIGTERM而不是SIGKILL。

我应该补充一点,这2种方法不适用于所有shell,例如,它不适用于csh
非序列号

38

使用killall,

killall vi

这将杀死所有名为“ vi”的命令

您也可以添加一个信号,例如SIGKILL

killall -9 vi


没错,您也可以添加所需的信号,例如killall -9 vi
Hola Soy Edu Feliz Navidad 2012年

1
我不认为killall是它的纳粹:按文件杀死仅适用于在执行过程中保持打开状态的可执行文件,即,不能以这种方式杀死不纯净的可执行文件。键入killall名称可能在非Linux系统上没有理想的效果,特别是当由特权用户完成时。如果我要删除某些非Linux进程的许多实例怎么办?killall -w不会检测进程是否消失,而是由两次扫描之间具有相同PID的新进程替换。如果进程更改了名称,killall可能无法正确匹配它们。
黑暗骑士

13
请注意,这仅适用于Linux和BSD。在Solaris和其他一些系统killall上,其名称所暗示的功能完全符合它的要求……它杀死了init进程。
鲍比(Bobby)2012年

2
在AIX上,它“取消启动的所有进程,但产生killall进程的进程除外”。
八比特通

31

pkill如果可以的话(LinuxFreeBSDNetBSDOpenBSDSolaris),这是我的建议。您可以通过命令名称,完整的命令行或其他条件指定进程。例如,pkill vi杀死所有命令名称包含substring的程序vi。要杀死仅被调用的进程vi,请使用pkill -x vi。要仅vi终止以最后一个参数结尾的进程.conf,请使用pkill -fx 'vi.*\.conf'

要查看pkill向其发送信号的PID的列表,请使用pgrep,其语法完全相同,但不接受信号名称或数字。要查看有关这些过程的更多信息,请运行

ps -p "$(pgrep …)"

在Linux下,您需要ps -p $(pgrep -d, …)代替(这是一个错误:Linux ps不兼容POSIX)。

标识要杀死的进程的另一种常见方法是打开了某个文件的进程(可以是该进程的可执行文件)。您可以通过以下方式列出这些内容fuser:用于fuser -k向他们发送信号。例如,fuser -k /usr/bin/find杀死的所有正在运行的项目find

如果有一个失控的流程一直在分叉,则可能需要立即杀死整个流程组。流程组由其领导者的否定标识,这是该组中所有流程的祖先流程。要查看某个进程所属的进程组,请运行ps -o pgid(加上任何选项以选择要显示的进程)。如果您确定要终止的进程组长1234和它的所有儿童,运行kill -1234kill -HUP -1234或其他任何信号。

如果找不到更好的方法,请使用ps适当的选项列出所有进程并使用grep或其他一些文本过滤命令对其进行过滤。注意不要意外地使碰巧正在运行具有相似名称或包含该名称的参数的命令的其他进程匹配。例如:

kill $(ps -o pid -o comm | awk '$2 == "vi" {print $1}')

请记住,您的grepawk命令本身可能会在ps输出中列出(ps并且过滤命令是并行启动的,因此它是否显示取决于时间)。如果命令参数包含在ps输出中,这尤其重要。


非常感谢,这真的很棒。您所提供的只是一种教程。再次感谢 。投票最多
黑暗骑士

6

pkill这里很好。您可以给它提供很多参数来完善模式。


并非在所有UNIX上都可用,并且在问题中没有提及特定的UNIX或类似UNIX的操作系统。
AugustBitTony 2012年

@EightBitTony pkill在Linux,BSD和Solaris-afaik上可用。所以它的传播比更大killall
Nils 2012年

我同意,但是killall的问题甚至更大,因为有多个同名工具,它们的行为似乎大不相同。我也不喜欢杀戮的答案。pkill在AIX或HP-UX上不存在,尽管有些人喜欢相信,但全世界仍然有大量基于非Linux UNIX的软件。
AugustBitTony 2012年

1
@EightBitTony这就是为什么您的答案被接受的原因。但是我不会在Solaris(也是Unix)上使用它。
Nils 2012年

6

最简单的方法是首先使用以下命令检查您是否获得了正确的进程ID:

pgrep -f [part_of_a_command]

如果结果符合预期。与:

pkill -f [part_of_a_command]

或使用:pgrep -f "command name"
Magne

3

有趣的是没有人提到这一件事。pidof输出与传递的进程名称匹配的以空格分隔的进程的pid。这样,您可以直接使用其输出而kill无需管道。在Arch Linux上,我使用

kill -9 $(pidof <proc name>)

该解决方案的不利之处在于它不允许使用正则表达式。


0

我建议你试试pkill

例如: ps -ef | pkill -f command

要显示所有要杀死的进程的列表,请尝试pgrep

例如: ps -ef | pgrep -f command


1
用管道输送输入ps -efpkill或的目的是什么pgrep?这些命令不从标准输入中读取。
库萨兰达

0

您可以使用以下命令杀死多个不同的进程

pkill -9 -f "\.\/.+\s\.|process1|process2|process3\[^"

请注意,这将杀死与上述模式匹配的进程,process1abc process2def process3ghi也将被杀死。


-1

pgrep "name-of-application" | xargs kill -9

很容易记住,并且对我来说很好。


-2
$ ps -eaf  | grep "xyz" | grep -v grep | awk 'print $2' | xargs kill

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.