在 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 时,进程管理就成了一个问题,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 窗口后,此类进程仍然经常在后台以不同的“奇怪”名称运行。没有简单的方法可以“kill 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 的例子很好。它启动的所有子进程可能会非常混乱。

© . All rights reserved.