了解如何使用ps、kill和killall命令来终止进程并回收系统资源。
在Linux中,每个程序和守护程序daemon都是一个“进程process”。大多数进程代表一个正在运行的程序。而另外一些程序可以派生出其他进程,比如说它会侦听某些事件的发生,然后对其做出响应。并且每个进程都需要一定的内存和处理能力。你运行的进程越多,所需的内存和CPU使用周期就越多。在老式电脑(例如我使用了7年的笔记本电脑)或轻量级计算机(例如树莓派)上,如果你关注过后台运行的进程,就能充分利用你的系统。
你可以使用ps命令来查看正在运行的进程。你通常会使用ps命令的参数来显示出更多的输出信息。我喜欢使用-e参数来查看每个正在运行的进程,以及-f参数来获得每个进程的全部细节。以下是一些例子:
$psPIDTTYTIMECMD88000pts/000:00:00bash88052pts/000:00:00ps88053pts/000:00:00head
$ps-e|headPIDTTYTIMECMD1?00:00:50systemd2?00:00:00kthreadd3?00:00:00rcu_gp4?00:00:00rcu_par_gp6?00:00:02kworker/0:0H-events_highpri9?00:00:00mm_percpu_wq10?00:00:01ksoftirqd/011?00:00:12rcu_sched12?00:00:00migration/0
$ps-ef|headUIDPIDPPIDCSTIMETTYTIMECMDroot10013:51?00:00:50/usr/lib/systemd/systemd--switched-root--system--deserialize36root20013:51?00:00:00[kthreadd]root32013:51?00:00:00[rcu_gp]root42013:51?00:00:00[rcu_par_gp]root62013:51?00:00:02[kworker/0:0H-kblockd]root92013:51?00:00:00[mm_percpu_wq]root102013:51?00:00:01[ksoftirqd/0]root112013:51?00:00:12[rcu_sched]root122013:51?00:00:00[migration/0]
最后的例子显示最多的细节。在每一行,UID(用户ID)显示了该进程的所有者。PID(进程ID)代表每个进程的数字ID,而PPID(父进程ID)表示其父进程的数字ID。在任何Unix系统中,进程是从1开始编号,是内核启动后运行的第一个进程。在这里,systemd是第一个进程,它催生了kthreadd,而kthreadd还创建了其他进程,包括rcu_gp、rcu_par_gp等一系列进程。
使用kill命令来管理进程
系统会处理大多数后台进程,所以你不需要操心这些进程。你只需要关注那些你所运行的应用创建的进程。虽然许多应用一次只运行一个进程(如音乐播放器、终端模拟器或游戏等),但其他应用则可能创建后台进程。其中一些应用可能当你退出后还在后台运行,以便下次你使用的时候能快速启动。
当我运行Chromium(作为谷歌Chrome浏览器所基于的开源项目)时,进程管理便成了问题。Chromium在我的笔记本电脑上运行非常吃力,并产生了许多额外的进程。现在我仅打开五个选项卡,就能看到这些Chromium进程:
$ps-ef|fgrepchromiumjhall66221[...]/usr/lib64/chromium-browser/chromium-browser[...]jhall66230[...]/usr/lib64/chromium-browser/chromium-browser[...][...]jhall66861[...]/usr/lib64/chromium-browser/chromium-browser[...]jhall6732965132015:45pts/000:00:00grep-Fchromium
我已经省略一些行,其中有20个Chromium进程和一个正在搜索“chromium"字符的grep进程。
$ps-ef|fgrepchromium|wc-l21
但是在我退出Chromium之后,这些进程仍旧运行。如何关闭它们并回收这些进程占用的内存和CPU呢?
kill命令能让你终止一个进程。在最简单的情况下,你告诉kill命令终止你想终止的进程的PID。例如,要终止这些进程,我需要对20个Chromium进程ID都执行kill命令。一种方法是使用命令行获取Chromium的PID,而另一种方法针对该列表运行kill:
$ps-ef|fgrep/usr/lib64/chromium-browser/chromium-browser|awk'{print$2}'662216623066239662576626266283662846628566324663376636066370663866640266503665396659566734668486686169702$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参数,来让killkill在停止每个进程之前提示你。
killall还支持使用-o或--older-than参数来查找比特定时间更早的进程。例如,如果你发现了一组已经运行了好几天的恶意进程,这将会很有帮助。又或是,你可以查找比特定时间更晚的进程,例如你最近启动的失控进程。使用-y或--young-than参数来查找这些进程。
其他管理进程的方式
进程管理是系统维护重要的一部分。在我作为Unix和Linux系统管理员的早期职业生涯中,杀死非法作业的能力是保持系统正常运行的关键。在如今,你可能不需要亲手在Linux上的终止流氓进程,但是知道kill和killall能够在最终出现问题时为你提供帮助。
你也能寻找其他方式来管理进程。在我这个案例中,我并不需要在我退出浏览器后,使用kill或killall来终止后台Chromium进程。在Chromium中有个简单设置就可以进行控制:
不过,始终关注系统上正在运行哪些进程,并且在需要的时候进行干预是一个明智之举。