在 Linux 系統中,了解哪些行程正在開啟檔案是一項重要的任務,特別是當您需要追蹤系統性能問題、解決檔案鎖定問題或檢查網絡連線時。這就是 lsof(List Open Files)指令派上用場的地方。lsof 允許您查看正在系統上運行的行程所開啟的所有檔案。在這篇文章中,我們將深入探討 lsof 的使用方法,並提供一些實用的範例。
lsof 是什麼?
lsof 是一個強大的命令列工具,它提供了有關系統上行程和檔案的詳細信息。它可以幫助您確定哪些行程正在存取特定檔案,或者哪些檔案被特定行程開啟。lsof 的名稱是 “List Open Files” 的縮寫,它的功能確實如其名稱所示:列出開啟的檔案。
lsof 基本指令
在開始使用 lsof 之前,您需要確保已經安裝了它。通常,lsof 可以在大多數 Linux 發行版的軟件存儲庫中找到,您可以使用包管理器進行安裝。
一旦安裝完成,您可以使用以下基本語法來執行 lsof:
lsof [選項]
這是一些常用的 lsof 選項:
-i
:列出所有網絡相關的開啟檔案。-c
:僅列出特定行程名稱相關的開啟檔案。-u
:僅列出特定使用者相關的開啟檔案。-s
選項來篩選特定的狀態。
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
COMMAND
:這是正在執行的行程的名稱。它顯示了開啟檔案的行程或程式。PID
:這是行程的進程識別碼(Process ID),唯一標識了每個正在運行的行程。USER
:這是執行行程的使用者名稱。它顯示了哪個使用者正在運行這個行程。FD
:這是檔案描述符(File Descriptor),它表示了行程正在使用的檔案或資源的描述符編號。TYPE
:這個欄位指示了開啟的檔案的類型,例如 REG(一般檔案)、DIR(目錄)、CHR(字元設備)、FIFO(命名管道)等等。DEVICE
:這是開啟檔案所在的裝置編號。SIZE/OFF
:這個欄位包含了有關檔案大小或偏移量(對於檔案來說)的資訊。對於目錄和其他資源,可能顯示不同的資訊。NODE
:對於磁碟上的一些檔案,這是節點編號。NAME
:這是開啟檔案的名稱或路徑。
lsof 查看行程開啟的檔案
現在,讓我們深入了解如何使用 lsof 來查看行程開啟的檔案。
列出所有行程的開啟檔案
要列出系統上所有行程開啟的檔案,只需執行以下命令:
lsof
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 253,1 4096 24 /
init 1 root cwd DIR 253,1 4096 24 /
bash 1203 user cwd DIR 253,1 4096 24 /home/user
...
這將顯示系統上所有行程的開啟檔案列表,包括檔案描述符、行程ID、使用者、檔案類型等詳細信息。
針對特定行程列出開啟檔案
如果您只對特定行程感興趣,可以使用 -c
選項來列出它們開啟的檔案。例如,要查看名稱為 “apache2” 的行程開啟的檔案,可以執行:
lsof -c apache2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
apache2 1234 www-data cwd DIR 253,1 4096 24 /var/www
apache2 1234 www-data txt REG 253,1 987654 12 /usr/sbin/apache2
...
這將顯示所有與 “apache2” 相關的開啟檔案。
查詢開啟指定檔案的行程
lsof /path/to/specific/file
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
process 1234 user 3w REG 253,1 1024 42 /path/to/specific/file
指定使用者的行程
lsof -u username
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
process1 1234 username 3r REG 253,1 1024 42 /file1
process2 5678 username 2w REG 253,1 2048 56 /file2
...
這個指令將列出指定使用者所開啟的所有檔案。
根據 PID 列出所開啟的檔案
lsof -p 1234
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
process 1234 username 3w REG 253,1 1024 42 /file1
process 1234 username 4r REG 253,1 2048 56 /file2
...
這個指令將列出特定 PID 的行程所開啟的所有檔案。
lsof 多條件
AND 運算
您可以使用多個選項進行 AND 運算,以縮小搜尋範圍。例如,您可以查詢特定使用者開啟的指定檔案,如下所示:
lsof -u username -c processname /path/to/specific/file
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
process 1234 username 3w REG 253,1 1024 42 /path/to/specific/file
這個指令結合了多個選項,以確保只列出指定使用者特定行程開啟的指定檔案。
排除條件
有時您可能想要排除特定條件下的行程或檔案。您可以使用 ^
選項來排除特定條件,如下所示:
lsof -u ^excludeuser
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
process1 1234 otheruser 3r REG 253,1 1024 42 /file1
process2 5678 anotheruser 2w REG 253,1 2048 56 /file2
...
這個指令將列出除了 excludeuser
以外的所有使用者開啟的檔案。
這個指令將列出特定 PID 1234的行程所開啟的所有檔案。
lsof 列出網絡相關的開啟檔案
lsof 也可以用於查看網絡相關的開啟檔案。使用 -i
選項,您可以列出正在進行的網絡連線以及相關的行程和檔案。例如,要查看所有的 TCP 連線,可以執行:
lsof -i tcp
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 567 root 3u IPv4 12345 0t0 TCP *:ssh (LISTEN)
httpd 789 apache 4u IPv6 23456 0t0 TCP *:http (LISTEN)
...
列出 80 連接埠的網路連線
lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 1234 apache 4u IPv6 23456 0t0 TCP *:http (LISTEN)
httpd 5678 apache 6u IPv6 23457 0t0 TCP 192.168.1.2:12345->192.168.1.3:80 (ESTABLISHED)
...
這個指令將列出所有與 80 連接埠有關的網路連線,包括正在監聽該連接埠的行程以及已建立的連線。
列出所有處於 LISTEN 狀態的 TCP 網路連線
lsof -i -n -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 1234 root 3u IPv4 12345 0t0 TCP *:ssh (LISTEN)
httpd 5678 apache 4u IPv6 23456 0t0 TCP *:http (LISTEN)
...
這個指令將列出所有處於 LISTEN 狀態的 TCP 網路連線。首先使用 lsof -i -n
列出所有網路連線,然後使用 grep
過濾出包含 “LISTEN” 和 “TCP” 的行。
列出已建立的 TCP 網路連線
lsof -i -n -sTCP:ESTABLISHED
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 1234 apache 6u IPv6 23457 0t0 TCP 192.168.1.2:12345->192.168.1.3:80 (ESTABLISHED)
ssh 5678 user 4u IPv4 34567 0t0 TCP 192.168.1.4:ssh->203.0.113.5:12345 (ESTABLISHED)
...
這個指令將列出所有已建立的 TCP 網路連線,包括相關的行程和連線詳細信息。使用 -E
選項來啟用正則表達式模式,以匹配 “ESTABLISHED” 和 “TCP”。
lsof 實際範例應用
現在,讓我們看一些實際的範例,展示 lsof 如何幫助您解決實際問題。
監視網絡連線
假設您想要監視您的伺服器上的網絡連線,以確保它們正常運作。您可以使用以下命令:
lsof -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 567 root 3u IPv4 12345 0t0 TCP *:ssh (LISTEN)
httpd 789 apache 4u IPv6 23456 0t0 TCP *:http (LISTEN)
...
這將列出所有正在進行的網絡連線,包括它們的狀態、本地地址、遠端地址等。
找出佔用磁碟空間的行程
如果您的磁碟空間快要用完,但您不確定哪些行程佔用了大部分空間,您可以使用 lsof 來查找。以下命令將列出佔用最多磁碟空間的行程:
lsof | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10
lsof
:這是 lsof 命令的起始部分,它會列出系統上所有行程開啟的檔案。這將是一個長列表,包括許多行程和相關的檔案信息。awk '{print $1}'
:通過管道|
將 lsof 的輸出傳遞給awk
命令。awk
是一個用於文本處理的強大工具,這裡我們使用它來提取每行的第一個字段,也就是行程名稱。$1
代表第一個字段。sort
:再次使用管道,將awk
的輸出傳遞給sort
命令。sort
會按照行程名稱的字母順序對輸入進行排序。這一步是為了確保相同行程的檔案會被連續列在一起。uniq -c
:接下來,我們使用uniq
命令來刪除連續相同的行程名稱,同時計算每個不同行程名稱出現的次數。-c
選項用於計數。sort -nr
:再次使用sort
命令,但這次是對計數結果進行排序。-n
選項表示按數值大小排序,-r
選項表示以降序(由高到低)排序。這樣,行程名稱數量最多的將排在前面。head -n 10
:最後,我們使用head
命令來提取前十行,這些行將是佔用磁碟空間最多的行程。-n 10
選項指定要提取的行數。
預期輸出結果(這只是示例,實際結果會根據系統狀況而變化):
1245 chrome
987 firefox
543 apache2
432 systemd
321 sshd
210 gnome-shell
189 mysql
178 pulseaudio
123 docker
102 kdeinit
這將列出佔用空間最多的前十個行程。
解決無法刪除檔案的問題
有時您可能無法刪除某個檔案,因為它正在被其他行程使用。使用 lsof,您可以查看哪個行程佔用了該檔案,以便采取相應的措施。
lsof /path/to/file
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
process 1234 user 3w REG 253,1 1024 42 /path/to/file
這將顯示正在使用指定檔案的行程。
注意事項
在使用 lsof 時,有一些注意事項需要考慮:
- 使用權限
- lsof 需要足夠的權限才能訪問某些系統資訊,因此您可能需要以 root 或具有適當權限的使用者身份運行它,特別是當您希望查看所有行程的開啟檔案時。
- 潛在的性能影響
- 執行 lsof 可能對系統性能產生一定影響,特別是當您運行它來監視網絡連線或查找佔用大量資源的行程時。請謹慎使用,特別是在生產環境中。
- 安全性考慮
- 使用 lsof 時,要謹慎確保您不會泄露敏感資訊,因為它可以顯示有關正在運行的行程和檔案的詳細信息。
延伸學習
lsof 是一個強大的工具,可幫助您深入了解系統中行程和檔案之間的關係。這篇文章提供了一個簡要的概述,並介紹了一些常見的使用情境。通過學習如何使用 lsof,您可以更好地管理和監視您的 Linux 系統。希望這篇文章對您有所幫助!
- 中文參考資料:
- 英文參考資料:
延伸閱讀:什麼是 Linux I/O 標準輸入輸出和管線 ? 超詳細範例說明與教學
延伸閱讀:如何在 Linux 中設定防火牆 ? CentOS firewall-cmd 設定防火牆規則與 firewall zones 教學