在 Linux 上使用 kill 和 killall 管理进程

了解如何使用 ps、kill 和 killall 命令终止进程并回收系统资源。
92 位读者喜欢这篇文章。
How Linux became my job

Opensource.com

在 Linux 中,每个程序和守护进程都是一个“进程”。大多数进程代表一个正在运行的程序。其他程序可以派生出其他进程,例如监听特定事件发生然后做出响应的进程。并且每个进程都需要一定数量的内存和处理能力。您运行的进程越多,您需要的内存和 CPU 周期就越多。在较旧的系统上,例如我的七年旧笔记本电脑或较小的计算机(如 Raspberry Pi),如果您密切关注后台运行的进程,则可以最大限度地利用系统。

您可以使用 ps 命令获取正在运行的进程列表。您通常需要为 ps 提供一些选项,以在其输出中显示更多信息。我喜欢使用 -e 选项来查看系统上运行的每个进程,以及 -f 选项来获取有关每个进程的完整详细信息。以下是一些示例

$ ps
    PID TTY          TIME CMD
  88000 pts/0    00:00:00 bash
  88052 pts/0    00:00:00 ps
  88053 pts/0    00:00:00 head
$ ps -e | head
    PID TTY          TIME CMD
      1 ?        00:00:50 systemd
      2 ?        00:00:00 kthreadd
      3 ?        00:00:00 rcu_gp
      4 ?        00:00:00 rcu_par_gp
      6 ?        00:00:02 kworker/0:0H-events_highpri
      9 ?        00:00:00 mm_percpu_wq
     10 ?        00:00:01 ksoftirqd/0
     11 ?        00:00:12 rcu_sched
     12 ?        00:00:00 migration/0
$ ps -ef | head
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 13:51 ?        00:00:50 /usr/lib/systemd/systemd --switched-root --system --deserialize 36
root           2       0  0 13:51 ?        00:00:00 [kthreadd]
root           3       2  0 13:51 ?        00:00:00 [rcu_gp]
root           4       2  0 13:51 ?        00:00:00 [rcu_par_gp]
root           6       2  0 13:51 ?        00:00:02 [kworker/0:0H-kblockd]
root           9       2  0 13:51 ?        00:00:00 [mm_percpu_wq]
root          10       2  0 13:51 ?        00:00:01 [ksoftirqd/0]
root          11       2  0 13:51 ?        00:00:12 [rcu_sched]
root          12       2  0 13:51 ?        00:00:00 [migration/0]

最后一个示例显示了最详细的信息。在每一行中,UID(用户 ID)显示进程的所有者用户。PID(进程 ID)代表每个进程的数字 ID,PPID(父进程 ID)显示派生此进程的进程的 ID。在任何 Unix 系统中,进程都从 PID 1 开始计数,PID 1 是内核启动后运行的第一个进程。在这里,systemd 是第一个进程,它派生了 kthreadd。而 kthreadd 创建了其他进程,包括 rcu_gprcu_par_gp 和许多其他进程。

使用 kill 命令进行进程管理

系统会自行处理大多数后台进程,因此您无需担心它们。您只需参与管理您创建的任何进程,通常是通过运行应用程序。虽然许多应用程序一次运行一个进程(想想您的音乐播放器或终端模拟器或游戏),但其他应用程序可能会创建后台进程。其中一些进程可能会在您退出应用程序后继续运行,以便下次启动应用程序时可以快速恢复工作。

当我运行 Chromium(Google Chrome 浏览器的开源基础)时,进程管理就成了一个问题。Chromium 使我的笔记本电脑运行非常吃力,并启动了许多额外的进程。现在,我可以看到这些 Chromium 进程正在运行,并且只打开了五个标签页

$ ps -ef | fgrep chromium
jhall      66221   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
jhall      66230   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
[...]
jhall      66861   [...]  /usr/lib64/chromium-browser/chromium-browser [...]
jhall      67329   65132  0 15:45 pts/0    00:00:00 grep -F chromium

我省略了一些行,但有 20 个 Chromium 进程和一个 grep 进程正在搜索字符串“chromium”。

$ ps -ef | fgrep chromium | wc -l
21

但是,在我退出 Chromium 后,这些进程仍然处于打开状态。您如何关闭它们并回收这些进程占用的内存和 CPU 呢?

kill 命令允许您终止进程。在最简单的情况下,您告诉 kill 您要停止的进程的 PID。例如,要终止这些进程中的每一个,我需要对 20 个 Chromium 进程 ID 中的每一个执行 kill 命令。一种方法是使用命令行获取 Chromium PID,另一个命令行对该列表运行 kill

$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}'
66221
66230
66239
66257
66262
66283
66284
66285
66324
66337
66360
66370
66386
66402
66503
66539
66595
66734
66848
66861
69702

$ ps -ef | fgrep /usr/lib64/chromium-browser/chromium-browser | awk '{print $2}' > /tmp/pids
$ kill $( cat /tmp/pids)

最后两行是关键。第一个命令行生成 Chromium 浏览器的进程 ID 列表。第二个命令行对该进程 ID 列表运行 kill 命令。

介绍 killall 命令

一次停止大量进程的更简单方法是使用 killall 命令。正如您可能从名称中猜到的那样,killall 终止所有与名称匹配的进程。这意味着我们可以使用此命令来停止所有恶意 Chromium 进程。这就像这样简单

$ killall /usr/lib64/chromium-browser/chromium-browser

但要小心使用 killall。此命令可以终止任何与您提供的名称匹配的进程。这就是为什么我喜欢首先使用 ps -ef 来检查我正在运行的进程,然后针对我要停止的命令的确切路径运行 killall

您可能还想使用 -i--interactive 选项来要求 killall 在停止每个进程之前提示您。

killall 还支持使用 -o--older-than 选项选择比特定时间更旧的进程的选项。如果您发现一组恶意进程已经无人值守地运行了几天,这将非常有用。或者您可以选择比特定时间更年轻的进程,例如您最近启动的失控进程。使用 -y--younger-than 选项来选择这些进程。

管理进程的其他方法

进程管理可能是系统维护的重要组成部分。在我早期作为 Unix 和 Linux 系统管理员的职业生涯中,终止逃逸作业的能力是保持系统正常运行的有用工具。您可能不需要在现代 Linux 桌面中终止恶意进程,但了解 killkillall 可以在事情最终出错时为您提供帮助。

您还可以寻找其他管理进程的方法。就我而言,在我退出浏览器后,我实际上不需要使用 killkillall 来停止后台 Chromium 进程。Chromium 中有一个简单的设置可以控制这一点

Chromium background processes setting

尽管如此,密切关注系统上运行的进程并了解如何在需要时管理它们始终是一个好主意。

接下来阅读什么
标签
photo of Jim Hall
Jim Hall 是一位开源软件倡导者和开发人员,以 GNOME 中的可用性测试以及 FreeDOS 的创始人兼项目协调员而闻名。

7 条评论

Chromium 的例子不错,但有时通过主程序名称进行过滤是不够的 - 尤其是 wine 进程。

Wine/Steam Proton 是启动 Windows 游戏的绝佳工具,但不幸的是 - 它经常无法正常工作和/或冻结。即使关闭所有 wine 窗口后,此类进程通常仍会在后台以不同的“怪异”名称运行。没有简单的方法可以“杀死 wine” - 有大量的 fork 进程,并且所有这些进程看起来都像“正常”的 Linux 进程。

我的解决方案是

`pgrep -af C:\\\\`

此命令将显示在其 COMMAND 中包含 C:\ 的 PID。至少在我的系统上,所有 wine 模拟程序都“假装”从“C:\”启动,即使 Linux 上不存在这样的东西。所有此类进程都可以通过命令 `pkill -9 -f C:\\\\` 杀死(-9 是因为 wine 经常冻结,而“正常”的 kill 对此类进程不起作用)。

PS. Chromium 是 Chrome 的开源部分。Chrome 存在的主要原因是为 Google 收集数据(并控制互联网 - 遗憾的是成功了)。因此 - Google 不喜欢有人试图关闭他们的数据挖掘终端是可以理解的。因此,当您关闭所有 Chrome 窗口时 - 实际上您只是隐藏了它们。真正的退出隐藏在“汉堡”菜单中,因此普通用户甚至不知道 Google 终端一直在监听(在 Windows 世界中,情况甚至更复杂 - 即使在真正的“Chrome 退出”之后,也始终有 Google 服务在运行……)。

很棒的文章。感谢分享。我学到了一些新知识。我用过 ps 和 kill,但从未使用过 killall。您给了我一些新工具。

很有帮助!

不错

嗨 Jim
不错的文章。我喜欢您可以在 Linux 中管理每个进程的方式。Chromium 的例子很棒。它启动的所有子进程可能会非常混乱。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.