在 Linux 上使用 kill 和 killall 命令來(lái)管理進(jìn)程
了解如何使用 ps、kill 和 killall 命令來(lái)終止進(jìn)程并回收系統(tǒng)資源。
在 Linux 中,每個(gè)程序和守護(hù)程序都是一個(gè)“進(jìn)程”。 大多數(shù)進(jìn)程代表一個(gè)正在運(yùn)行的程序。而另外一些程序可以派生出其他進(jìn)程,比如說(shuō)它會(huì)偵聽(tīng)某些事件的發(fā)生,然后對(duì)其做出響應(yīng)。并且每個(gè)進(jìn)程都需要一定的內(nèi)存和處理能力。你運(yùn)行的進(jìn)程越多,所需的內(nèi)存和 CPU 使用周期就越多。在老式電腦(例如我使用了 7 年的筆記本電腦)或輕量級(jí)計(jì)算機(jī)(例如樹(shù)莓派)上,如果你關(guān)注過(guò)后臺(tái)運(yùn)行的進(jìn)程,就能充分利用你的系統(tǒng)。
你可以使用 ps
命令來(lái)查看正在運(yùn)行的進(jìn)程。你通常會(huì)使用 ps
命令的參數(shù)來(lái)顯示出更多的輸出信息。我喜歡使用 -e
參數(shù)來(lái)查看每個(gè)正在運(yùn)行的進(jìn)程,以及 -f
參數(shù)來(lái)獲得每個(gè)進(jìn)程的全部細(xì)節(jié)。以下是一些例子:
$ 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]
最后的例子顯示最多的細(xì)節(jié)。在每一行,UID
(用戶(hù) ID)顯示了該進(jìn)程的所有者。PID
(進(jìn)程 ID)代表每個(gè)進(jìn)程的數(shù)字 ID,而 PPID
(父進(jìn)程 ID)表示其父進(jìn)程的數(shù)字 ID。在任何 Unix 系統(tǒng)中,進(jìn)程是從 1 開(kāi)始編號(hào),是內(nèi)核啟動(dòng)后運(yùn)行的第一個(gè)進(jìn)程。在這里,systemd
是第一個(gè)進(jìn)程,它催生了 kthreadd
,而 kthreadd
還創(chuàng)建了其他進(jìn)程,包括 rcu_gp
、rcu_par_gp
等一系列進(jìn)程。
使用 kill 命令來(lái)管理進(jìn)程
系統(tǒng)會(huì)處理大多數(shù)后臺(tái)進(jìn)程,所以你不需要操心這些進(jìn)程。你只需要關(guān)注那些你所運(yùn)行的應(yīng)用創(chuàng)建的進(jìn)程。雖然許多應(yīng)用一次只運(yùn)行一個(gè)進(jìn)程(如音樂(lè)播放器、終端模擬器或游戲等),但其他應(yīng)用則可能創(chuàng)建后臺(tái)進(jìn)程。其中一些應(yīng)用可能當(dāng)你退出后還在后臺(tái)運(yùn)行,以便下次你使用的時(shí)候能快速啟動(dòng)。
當(dāng)我運(yùn)行 Chromium(作為谷歌 Chrome 瀏覽器所基于的開(kāi)源項(xiàng)目)時(shí),進(jìn)程管理便成了問(wèn)題。 Chromium 在我的筆記本電腦上運(yùn)行非常吃力,并產(chǎn)生了許多額外的進(jìn)程?,F(xiàn)在我僅打開(kāi)五個(gè)選項(xiàng)卡,就能看到這些 Chromium 進(jìn)程:
$ 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
我已經(jīng)省略一些行,其中有 20 個(gè) Chromium 進(jìn)程和一個(gè)正在搜索 “chromium" 字符的 grep
進(jìn)程。
$ ps -ef | fgrep chromium | wc -l
21
但是在我退出 Chromium 之后,這些進(jìn)程仍舊運(yùn)行。如何關(guān)閉它們并回收這些進(jìn)程占用的內(nèi)存和 CPU 呢?
kill
命令能讓你終止一個(gè)進(jìn)程。在最簡(jiǎn)單的情況下,你告訴 kill
命令終止你想終止的進(jìn)程的 PID。例如,要終止這些進(jìn)程,我需要對(duì) 20 個(gè) Chromium 進(jìn)程 ID 都執(zhí)行 kill
命令。一種方法是使用命令行獲取 Chromium 的 PID,而另一種方法針對(duì)該列表運(yùn)行 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)
最后兩行是關(guān)鍵。第一個(gè)命令行為 Chromium 瀏覽器生成一個(gè)進(jìn)程 ID 列表。第二個(gè)命令行針對(duì)該進(jìn)程 ID 列表運(yùn)行 kill
命令。
介紹 killall 命令
一次終止多個(gè)進(jìn)程有個(gè)更簡(jiǎn)單方法,使用 killall
命令。你或許可以根據(jù)名稱(chēng)猜測(cè)出,killall
會(huì)終止所有與該名字匹配的進(jìn)程。這意味著我們可以使用此命令來(lái)停止所有流氓 Chromium 進(jìn)程。這很簡(jiǎn)單:
$ killall /usr/lib64/chromium-browser/chromium-browser
但是要小心使用 killall
。該命令能夠終止與你所給出名稱(chēng)相匹配的所有進(jìn)程。這就是為什么我喜歡先使用 ps -ef
命令來(lái)檢查我正在運(yùn)行的進(jìn)程,然后針對(duì)要停止的命令的準(zhǔn)確路徑運(yùn)行 killall
。
你也可以使用 -i
或 --interactive
參數(shù),來(lái)讓 killkill
在停止每個(gè)進(jìn)程之前提示你。
killall
還支持使用 -o
或 --older-than
參數(shù)來(lái)查找比特定時(shí)間更早的進(jìn)程。例如,如果你發(fā)現(xiàn)了一組已經(jīng)運(yùn)行了好幾天的惡意進(jìn)程,這將會(huì)很有幫助。又或是,你可以查找比特定時(shí)間更晚的進(jìn)程,例如你最近啟動(dòng)的失控進(jìn)程。使用 -y
或 --young-than
參數(shù)來(lái)查找這些進(jìn)程。
其他管理進(jìn)程的方式
進(jìn)程管理是系統(tǒng)維護(hù)重要的一部分。在我作為 Unix 和 Linux 系統(tǒng)管理員的早期職業(yè)生涯中,殺死非法作業(yè)的能力是保持系統(tǒng)正常運(yùn)行的關(guān)鍵。在如今,你可能不需要親手在 Linux 上的終止流氓進(jìn)程,但是知道 kill
和 killall
能夠在最終出現(xiàn)問(wèn)題時(shí)為你提供幫助。
你也能尋找其他方式來(lái)管理進(jìn)程。在我這個(gè)案例中,我并不需要在我退出瀏覽器后,使用 kill
或 killall
來(lái)終止后臺(tái) Chromium 進(jìn)程。在 Chromium 中有個(gè)簡(jiǎn)單設(shè)置就可以進(jìn)行控制:
Chromium background processes setting
不過(guò),始終關(guān)注系統(tǒng)上正在運(yùn)行哪些進(jìn)程,并且在需要的時(shí)候進(jìn)行干預(yù)是一個(gè)明智之舉。