本篇介紹如何使用 Linux 的 lsof 指令,查詢系統上各行程所開啟的檔案。

在 Linux 系統之下,幾乎所有的系統資源都是以檔案的形式呈現的(包含一般檔案、目錄、連結檔、裝置檔、管線檔、網路 socket 等),所以對於管理者來說,若要查詢一個程式使用了哪些系統資源,就可以透過它開啟的檔案來得知。


lsof 指令可以用來查詢行程所開啟的檔案列表,這個小工具對於系統管理者來說非常實用,而且也非常重要,以下是這個工具的使用方式與範例。

列出所有行程所開啟的檔案

直接執行 lsof 指令的話,可以列出系統上每一個行程所開啟的檔案列表:

# 列出所有行程所開啟的檔案
lsof

不過由於輸出的資料量太大了,通常我們不太會這樣使用。

查詢開啟指定檔案的行程

如果想要查詢目前正在開啟指定檔案的行程,可以在執行 lsof 時直接加上檔案的名稱與路徑。

以 GVim 編輯器來說,當它開啟檔案進行編輯時,會自動開啟一個 .swp 的隱藏檔,我們可以使用以下指令來驗證:

# 列出所有行程所開啟的檔案
lsof .my_file.txt.swp
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
gvim    7167 gtwang   14u   REG    8,6    12288 786944 .my_file.txt.swp

列出指定使用者所開啟的檔案

若要讓 lsof 列出指定用者所開啟的所有檔案,可以使用 -u 參數指定使用者名稱:

# 列出 gtwang 使用者所開啟的檔案
lsof -u gtwang

若要一次列出多位使用者所開啟的檔案,可以使用逗號分隔,或是使用多個 -u 參數來指定:

# 列出多位使用者所開啟的檔案
lsof -u user1,user2,user3

# 列出多位使用者所開啟的檔案
lsof -u user1 -u user2 -u user3

列出指定程式所開啟的檔案

如果想要列出指定程式所開啟的檔案,可以使用 -c 參數指定程式的名稱,例如列出 httpd 這個網頁伺服器所開啟的檔案:

# 列出 httpd 伺服器所開啟的檔案
lsof -c httpd

若要列出多個程式所開啟的檔案,可以使用多個 -c 參數來指定:

# 列出多個程式所開啟的檔案
lsof -c java -c httpd

多條件 AND 運算

lsof 可以同時指定多個篩選條件,預設的狀況下多個條件之間會以 OR 運算來結合,假設我們想要列出 root 使用者所開啟的檔案,或是 java 這個應用程式所開啟的檔案,就可以這樣寫:

# 多個條件(OR 運算)
lsof -u root -c java

而如果我們想要以 AND 運算來結合多個條件,可加上 -a 參數。例如若要列出 root 使用者執行 java 程式所開啟的檔案,可以這樣寫:

# 多個條件(AND 運算)
lsof -a -u root -c java

排除條件

如果想要排除特定的使用者所開啟的檔案,可以在使用者名稱之前加上 ^ 符號:

# 列出非 root 使用者所開啟的檔案
lsof -u ^root

這樣就會列出除了 root 之外,所有使用者所開啟的檔案。

根據 PID 列出所開啟的檔案

若要列出指定 PID 的行程所開啟的檔案,可以使用 -p 參數來指定 PID:

# 列出 PID 為 14662 的行程,所開啟的檔案
lsof -p 14662

若要同時根據多個 PID 列出開啟的檔案,一樣可以用逗號分隔多個 PID:

# 根據多個 PID 列出開啟的檔案
lsof -p 14662,14678,14979

網路連線

lsof-i 參數可以用來查詢所有的網路連線:

# 列出所有網路連線
lsof -i

若想只想要列出 TCP 或 UDP 的網路連線,可以在 -i 參數之後指定 tcpudp

# 列出所有 TCP 網路連線
lsof -i tcp

# 列出所有 UDP 網路連線
lsof -i udp

亦可指定連接埠,例如列出網頁伺服器的網路連線:

# 列出 80 連接埠的網路連線
lsof -i :80

這是一些其他的範例:

# 列出 SMTP 的網路連線
lsof -i :smtp

# 列出 3642 連接埠的 TCP 連線
lsof -i tcp:3642

# 列出 1 到 1024 連接埠的 TCP 網路連線
lsof -i :1-1024

若要列出所有處於 LISTEN 狀態的 TCP 網路連線,可以執行:

# 列出所有處於 LISTEN 狀態的 TCP 網路連線
lsof -i TCP -s TCP:LISTEN

列出已建立的 TCP 網路連線:

# 列出已建立的 TCP 網路連線
lsof -i TCP -s TCP:ESTABLISHED

參考資料:JavarevisitedHowtoForgeDaniel MiesslerLinux Handbook