lsof命令詳解
lsof 簡介
lsof
(list open files)是一個列出當前系統打開文件的工具。在linux環境中一切皆文件,通過文件不僅僅可以訪問常規數據,還可以訪問網絡連接和硬件。所以如傳輸控制協議 (TCP) 和用戶數據報協議 (UDP) 套接字等,系統在后台都為該應用程序分配了一個文件描述符,無論這個文件的本質如何,該文件描述符為應用程序與基礎操作系統之間的交互提供了通用接口。因為應用程序打開文件的描述符列表提供了大量關於這個應用程序本身的信息,因此通過lsof工具能夠查看這個列表對系統監測以及排錯將是很有幫助的。
lsof 命令解析
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root cwd DIR 253,0 224 64 / systemd 1 root rtd DIR 253,0 224 64 / systemd 1 root txt REG 253,0 1482128 67418805 /systemd systemd 1 root mem REG 253,0 20040 33619254 /usr/lib64
輸出各列信息的意義如下:
COMMAND: 進程的名稱
PID: 進程標識符
USER: 進程所有者
FD: 文件描述符,應用程序通過文件描述符識別該文件。每個進程都有自己的文件描述符表,因此FD可能會重名
TYPE: 文件類型
DEVICE: 指定磁盤的名稱
SIZE: 文件的大小
NODE: 索引節點(文件在磁盤上的標識)
NAME: 打開文件的確切名稱
查看進程打開文件
列出占用文件的進程
$ sudo lsof /home/mysql/ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 18522 mysql cwd DIR 253,0 4096 655378 /home/mysql sudo 18544 root cwd DIR 253,0 4096 655378 /home/mysql lsof 18545 root cwd DIR 253,0 4096 655378 /home/mysql lsof 18546 root cwd DIR 253,0 4096 655378 /home/mysql
可配合 +d
選項,表示/home/mysql
目錄及目錄下的文件,不包括子目錄
列出pid打開的文件
-p
選項,列出指定pid打開的文件,如果要多個,則用逗號隔開
$ sudo lsof -p 16273 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nano 16273 root cwd DIR 253,0 4096 1179649 /root
列出指定用戶打開的文件
-u
選項,列出指定用戶打開的文件
$ sudo lsof -u test1 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 16335 test1 cwd DIR 253,0 4096 1966556 /home/test1
列出指定進程名打開的文件
-c
選項,列出指定進程名打開的文件
sudo lsof -c java # 顯示command列中以java的所有打開的文件 sudo lsof -c java -c sh # 顯示command列中以java開頭或以sh開頭的打開的文件 sudo lsof -c ^java # 顯示command列中所有不以java開頭的打開的文件
查看網絡連接情況
-i
選項,可以列出網絡連接情況。語法格式如下:
lsof -i[46] [protocol] [@hostname|hostaddr] [:service|prot]
參數解析: 4/6:IPv4或IPv6 protocol:TCP或UDP hostname:主機名 hostaddr:ip地址 service:/etc/service中服務名,可寫多個 port:端口號,可寫多個
示例:
1. 查看IPv4網絡情況
$ lsof -i 4 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rpcbind 1599 rpc 6u IPv4 10168 0t0 UDP *:sunrpc rpcbind 1599 rpc 7u IPv4 10169 0t0 UDP *:926
2. 查看指定IP
-n
表示不進行IP域名反查,直接顯示ip地址
$ lsof -i @10.0.137.144 -n COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 16734 root 3u IPv4 14692046 0t0 TCP 10.0.137.144:ssh->10.0.2.136:49614 (ESTABLISHED) sshd 16736 test 3u IPv4 14692046 0t0 TCP 10.0.137.144:ssh->10.0.2.136:49614 (ESTABLISHED)
3. 查看指定IP及端口
$ sudo lsof -i @10.0.137.144:22 -n COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 16734 root 3u IPv4 14692046 0t0 TCP 10.0.137.144:ssh->10.0.2.136:49614 (ESTABLISHED) sshd 16736 test 3u IPv4 14692046 0t0 TCP 10.0.137.144:ssh->10.0.2.136:49614 (ESTABLISHED)
4. 查看指定端口
$ lsof -i :22 -n COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1095 root 3u IPv4 14032 0t0 TCP *:ssh (LISTEN) sshd 1095 root 4u IPv6 14034 0t0 TCP *:ssh (LISTEN) sshd 16734 root 3u IPv4 14692046 0t0 TCP 10.0.137.144:ssh->10.0.2.136:49614 (ESTABLISHED) sshd 16736 test 3u IPv4 14692046 0t0 TCP 10.0.137.144:ssh->10.0.2.136:49614 (ESTABLISHED)
5. 查看指定協議
$ sudo lsof -i UDP COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rsyslogd 17935 root 3u IPv4 11066422 0t0 UDP *:40296
=================================================================================================================================================================================================================================================================================================================================
lsof 常用參數
lsof語法格式是: lsof [options] filename
lsof abc.txt 顯示開啟文件abc.txt的進程 lsof -c abc 顯示abc進程現在打開的文件 lsof -c -p 1234 列出進程號為1234的進程所打開的文件 lsof -g gid 顯示歸屬gid的進程情況 lsof +d /usr/local/ 顯示目錄下被進程開啟的文件 lsof +D /usr/local/ 同上,但是會搜索目錄下的目錄,時間較長 lsof -d 4 顯示使用fd為4的進程 lsof -i 用以顯示符合條件的進程情況
lsof -i : 8080 顯示8080端口號的使用情況
lsof使用實例
查找誰在使用文件系統
在卸載文件系統時,如果該文件系統中有任何打開的文件,操作通常將會失敗。那么通過lsof可以找出那些進程在使用當前要卸載的文件系統,如下:
# lsof /GTES11/ COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME bash 4208 root cwd DIR 3,1 4096 2 /GTES11/
vim 4230 root cwd DIR 3,1 4096 2 /GTES11/
在這個示例中,用戶root 正在其/GTES11目錄中進行一些操作。一個 bash是實例正在運行,並且它當前的目錄為/GTES11,另一個則顯示的是vim正在編輯/GTES11下的文件。
要成功地卸載/GTES11,應該在通知用戶以確保情況正常之后,中止這些進程。 這個示例說明了應用程序的當前工作目錄非常重要,因為它仍保持着文件資源,並且可以防止文件系統被卸載。這就是為什么大部分守護進程(后台進程)將它們的目錄更改為根目錄、或服務特定的目錄(如 sendmail 示例中的 /var/spool/mqueue)的原因,以避免該守護進程阻止卸載不相關的文件系統。
恢復刪除的文件
當Linux計算機受到入侵時,常見的情況是日志文件被刪除,以掩蓋攻擊者的蹤跡。管理錯誤也可能導致意外刪除重要的文件,比如在清理舊日志時,意外地刪除了數據庫的活動事務日志。有時可以通過lsof來恢復這些文件。 當進程打開了某個文件時,只要該進程保持打開該文件,即使將其刪除,它依然存在於磁盤中。這意味着,進程並不知道文件已經被刪除,它仍然可以向打開該文件時提供給它的文件描述符進行讀取和寫入。除了該進程之外,這個文件是不可見的,因為已經刪除了其相應的目錄索引節點。
在/proc 目錄下,其中包含了反映內核和進程樹的各種文件。/proc目錄掛載的是在內存中所映射的一塊區域,所以這些文件和目錄並不存在於磁盤中,因此當我們對這些文件進行讀取和寫入時,實際上是在從內存中獲取相關信息。大多數與 lsof 相關的信息都存儲於以進程的 PID 命名的目錄中,即 /proc/1234 中包含的是 PID 為 1234 的進程的信息。每個進程目錄中存在着各種文件,它們可以使得應用程序簡單地了解進程的內存空間、文件描述符列表、指向磁盤上的文件的符號鏈接和其他系統信息。lsof 程序使用該信息和其他關於內核內部狀態的信息來產生其輸出。所以lsof 可以顯示進程的文件描述符和相關的文件名等信息。也就是我們通過訪問進程的文件描述符可以找到該文件的相關信息。
當系統中的某個文件被意外地刪除了,只要這個時候系統中還有進程正在訪問該文件,那么我們就可以通過lsof從/proc目錄下恢復該文件的內容。
假如由於誤操作將/var/log/messages文件刪除掉了,那么這時要將/var/log/messages文件恢復的方法如下:
首先使用lsof來查看當前是否有進程打開/var/logmessages文件,如下:
# lsof |grep /var/log/messages COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME syslogd 1283 root 2w REG 3,3 5381017 1773647 /var/log/messages (deleted)
從上面的信息可以看到 PID 1283(syslogd)打開文件的文件描述符為 2。同時還可以看到/var/log/messages已經標記被刪除了。
因此我們可以在 /proc/1283/fd/2 (fd下的每個以數字命名的文件表示進程對應的文件描述符)中查看相應的信息,如下:
# head -n 10 /proc/1283/fd/2 Aug 4 13:50:15 holmes86 syslogd 1.4.1: restart. Aug 4 13:50:15 holmes86 kernel: klogd 1.4.1, log source = /proc/kmsg started. Aug 4 13:50:15 holmes86 kernel: Linux version 2.6.22.1-8 (rooteverestbuilder.linux-ren.org) (gcc version 4.2.0) #1 SMP Wed Jul 18 11:18:32 EDT 2007 Aug 4 13:50:15 holmes86 kernel: BIOS-provided physical RAM map: Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000000000 - 000000000009f000 (usable) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000000009f000 - 00000000000a0000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 0000000000100000 - 000000001f7d3800 (usable) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 000000001f7d3800 - 0000000020000000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000e0000000 - 00000000f0007000 (reserved) Aug 4 13:50:15 holmes86 kernel: BIOS-e820: 00000000f0008000 - 00000000f000c000 (reserved)
從上面的信息可以看出,查看 /proc/8663/fd/15 就可以得到所要恢復的數據。如果可以通過文件描述符查看相應的數據,
那么就可以使用 I/O 重定向將其復制到文件中,如: cat /proc/1283/fd/2 > /var/log/messages 對於許多應用程序,尤其是日志文件和數據庫,這種恢復刪除文件的方法非常有用。
1.普通的文件 2.目錄 3.網絡文件系統的文件 4.字符設備文件
5.(函數)共享庫 6.管道,命名管道 7.符號鏈接
8.底層的socket字流,網絡socket,unix域名socket
9.在linux里面,大部分的東西都是被當做文件的…..還有其他很多
怎樣使用lsof
這里主要用案例的形式來介紹lsof 命令的使用
1.列出所有打開的文件:
lsof
備注: 如果不加任何參數,就會打開所有被打開的文件,建議加上一下參數來具體定位
2. 查看誰正在使用某個文件
lsof /filepath/file
3.遞歸查看某個目錄的文件信息
lsof +D /filepath/filepath2/
備注: 使用了+D,對應目錄下的所有子目錄和文件都會被列出
4. 比使用+D選項,遍歷查看某個目錄的所有文件信息 的方法
lsof | grep ‘/filepath/filepath2/’
5. 列出某個用戶打開的文件信息
lsof -u username
備注: -u 選項,u其實是user的縮寫
6. 列出某個程序所打開的文件信息
lsof -c mysql
備注: -c 選項將會列出所有以mysql開頭的程序的文件,其實你也可以寫成lsof | grep mysql,但是第一種方法明顯比第二種方法要少打幾個字符了
7. 列出多個程序多打開的文件信息
lsof -c mysql -c apache
8. 列出某個用戶以及某個程序所打開的文件信息
lsof -u test -c mysql
9. 列出除了某個用戶外的被打開的文件信息
lsof -u ^root
備注:^這個符號在用戶名之前,將會把是root用戶打開的進程不讓顯示
10. 通過某個進程號顯示該進行打開的文件
lsof -p 1
11. 列出多個進程號對應的文件信息
lsof -p 123,456,789
12. 列出除了某個進程號,其他進程號所打開的文件信息
lsof -p ^1
13 . 列出所有的網絡連接
lsof -i
14. 列出所有tcp 網絡連接信息
lsof -i tcp
15. 列出所有udp網絡連接信息
lsof -i udp
16. 列出誰在使用某個端口
lsof -i :3306
17. 列出誰在使用某個特定的udp端口
lsof -i udp:55
特定的tcp端口
lsof -i tcp:80
18. 列出某個用戶的所有活躍的網絡端口
lsof -a -u test -i
19. 列出所有網絡文件系統
lsof -N
20.域名socket文件
lsof -u
21.某個用戶組所打開的文件信息
lsof -g 5555
22. 根據文件描述列出對應的文件信息
lsof -d description(like 2)
23. 根據文件描述范圍列出文件信息
lsof -d 2-3
參考文章:
https://www.cnblogs.com/sparkbj/p/7161669.html
https://www.cnblogs.com/technologylife/p/9211289.html