在Linux上,我如何通过进程名称而不是PID来终止一个进程?

518

有时候当我尝试启动 Firefox 时,它会显示“Firefox 进程已经在运行”。因此我需要执行以下步骤:

jeremy@jeremy-desktop:~$ ps aux | grep firefox
jeremy    7451 25.0 27.4 170536 65680 ?        Sl   22:39   1:18 /usr/lib/firefox-3.0.1/firefox
jeremy    7578  0.0  0.3   3004   768 pts/0    S+   22:44   0:00 grep firefox
jeremy@jeremy-desktop:~$ kill 7451

我想要的是一个命令,可以为我完成所有操作。它将接受输入字符串并在进程列表中使用grep(或其他方式)查找它,并杀死输出中的所有进程:

jeremy@jeremy-desktop:~$ killbyname firefox

我尝试用PHP来实现它,但是exec('ps aux')似乎只会显示在PHP脚本中使用exec()执行的进程(所以它只会显示自己的进程)。


当我收到窗口提示Firefox已经在运行时,通常只需要等待一秒钟,然后就可以再次运行Firefox(当然,并不总是这样)。 - nuoritoveri
1
这是JohnB在这个答案中所说的最安全的方法:https://dev59.com/T2w15IYBdhLWcg3w0fAV#19733066 - tecnoshopbq
这是一个老问题,但您能否更改接受的答案?您标记的那个答案在许多进程中都会失败,例如JVM运行的进程。 - Luís de Sousa
1
对于任何参考此主题的人,在上面的评论中,Luis 引用了下面宣传 pkill -f "进程名称" 命令的答案... - Digger
18个回答

726

22
在杀死进程之前使用pgrep来弄清楚你要杀死的是什么是一个好习惯,特别是当使用“-f”选项时。 - Akrikos
1
pkill不是很友好。你不能像killall一样给它名称。 - Octopus
4
pkill -U <用户名>非常方便。我有一个Solaris Web服务器,实际的Web服务器守护进程被设置为一个带有自己用户的“服务”。因此,按用户指定是触发重启的一种简单/易用的方法。 - Raystorm
13
强制终止:pkill -9 火狐浏览器 - Justas
4
最好情况下,这样做只能成功一半。你至少需要使用 -f 标志来实现全面解决方案。 - Luís de Sousa

214

也可以使用:

pkill -f "Process name"

对我而言,它完美地发挥了作用。这正是我一直在寻找的东西。 未使用标志名称的pkill无法工作。

当设置-f时,将使用完整命令行进行模式匹配。


5
特别是在使用 wine 运行某些东西时,-f 选项确实是必须的。例如:pkill -f "EvilWindowsServer.exe" - CodeBrauer
1
这应该是被接受的答案。第一个答案在许多种程序中都会失败,例如那些在JVM上运行的程序。 - Luís de Sousa
4
我还需要添加-f标志才能杀死后台运行的Python脚本进程。 - Mason

72

你可以通过killall <name>命令按照名称杀死进程。

killall命令发送信号给运行任何指定命令的所有进程。如果未指定信号名称,则发送SIGTERM信号。

可以通过名称(例如-HUP-SIGHUP)或数字(例如-1)或选项-s来指定信号。

如果命令名称不是正则表达式(选项-r),并且包含斜杠(/),则选择执行该特定文件的进程进行杀死,而与它们的名称无关。

但是,如果您在ps aux中看不到该进程,您可能没有权限杀死它...


6
若要强制结束一个未响应的程序,请发送KILL信号而非TERM信号:killall -s KILL firefox - Martin Hansen

67

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

pgrep -f [part_of_a_command]

如果结果符合预期。请继续执行以下操作:

pkill -f [part_of_a_command]

如果进程被卡住,无法完成请求,您可以使用kill命令。

kill -9 $(pgrep -f [part_of_a_command])

如果你想保险起见,只终止你最初启动的进程,请添加-u以及你的用户名。

pkill -f [part_of_a_command] -u [username]

3
被低估的答案 - seven
3
pkill -f [part_of_a_command] didn't work. I used: kill -9 $(pgrep -f "part_of_a_command") - alercelik
pkill 只会向符合命令行中给定的条件的所有进程发送信号。有时进程会卡住,无法完成请求。kill -9 强制执行请求并终止进程。 - Tahsin Turkoz
1
好的解决方案,我只是为了安全起见,在使用它时在共享集群上添加了-u [用户名]。pgrep -f [部分命令] -u [用户名] - anilbey
1
谢谢@anilbey。我也会把这个加到我的帖子里。 - Tahsin Turkoz

57

稍微长一点的替代方案:

kill `pidof firefox`

31
pidof firefox | xargs kill -9 - hbt
3
这个可以在嵌入式设备上使用busybox :) - nwgat

34

杀掉所有在启动路径中含有snippet的进程。你可以通过将/directory/作为片段来杀死从某个目录启动的所有应用程序。当您从同一应用程序目录启动多个组件时,这非常有用。

ps ax | grep <snippet> | grep -v grep | awk '{print $1}' | xargs kill

* 如果有pgrep可用,我更倾向于使用它


5
这是一个经常出现的反模式组合。使用不匹配自身(或包含脚本名称)的正则表达式,并避免使用无用的 grep 命令。ps ax | awk '/[s]nippet/ { print $1 }' | xargs kill - tripleee
1
避免使用无用的grep命令并不能避免打错字,也不能保证在自动化过程中能够使用该命令来参数化<snippet>。 - Mike
这确实是最好的方法! - Abhinandan Dubey
很好奇为什么@tripleee的[s]不匹配awk进程本身? - andig
这是我在Windows上使用Git Bash所需的选项,因为其他工具不可用。谢谢! - ATutorMe
显示剩余3条评论

28

奇怪的是,我还没有看到像这样的解决方案:

kill -9 `pidof firefox`

它还可以像这样杀死多个进程(多个pid):

kill -9 `pgrep firefox`

我更喜欢使用pidof,因为它只有单行输出:

> pgrep firefox
6316
6565
> pidof firefox
6565 6316

当我执行这个命令时,出现了错误 kill: invalid number 'pidof myprogram'。这里有什么问题吗? - Brethlosze
今天这个救了我的命...我不想多写,但很高兴在这里找到它。谢谢啊。 - MilMike
1
来晚了,但以防其他人想知道... @Brethlosze 你使用了单引号,而命令需要反引号。 - spectras
谢谢!我会注意这些反引号的 :) - Brethlosze
你可以使用 pgrep ssh -d' ' 命令将输出显示在一行中。 - Mostafa Wael

24

使用 killall 命令:

killall processname

使用-9-KILL来强制终止程序(这些选项类似于kill命令)。


12

在Mac上,我找不到pgrep和pkill,而killall也不起作用,所以我写了一个简单的一行脚本:

export pid=`ps | grep process_name | awk 'NR==1{print $1}' | cut -d' ' -f1`;kill $pid

如果有更简单的方法,请分享。


1
哈哈,这是一个对于这个任务来说疯狂的命令。算了吧。你说那个简单的一行代码吗? :D简单就是killall。 - m3nda
@erm3nda :-) 同意。回头看起来是疯狂的。我不记得为什么当时我的Mac上killall命令无法运行了。 - Dhiraj
当你想要杀死某个Java进程(如“jboss”)时,这非常有用。在这种情况下,killall无法帮助。 - Jan M

8

使用grep查找和删除:

kill -9 `pgrep myprocess`

对我有用。在设置alias时遇到了一些麻烦,但通过转义\``字符,我成功让它工作:alias k = "kill -9 \pgrep xyz\\"` - user1300214

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接