您應該知道的UNIX工具之lsof

 轉自:http://blog.csdn.net/yetyongjin/article/details/7740373

這是“您應該知道的UNIX工具系列主題文章”的第三篇。在這篇文章裏,我將介紹一個很有用的工具—lsof。如果說netcat是網絡連接的瑞士軍刀,那麼我說lsofUNIX調試的瑞士軍刀。

Lsof嚴格遵循UNIX的哲學典範。它僅完成一項任務,並且做得極盡完美----它能夠列出某個進程所打開的文件信息。打開的文件可以是普通文件、目錄、NFS文件、塊文件、字符文件、共享庫、普通管道、命名管道、符號鏈接、socket流、網絡socketUNIX socket,等等等等。因爲UNIX世界裏,幾乎所有東西都是文件,所以,您可以想像lsof的用處是多麼的大。

 

您可以看看本主題系列的第一篇文章,關於 pipe viewer的介紹。如果您對這篇文章感興趣,那麼請訂閱我的  rss feed

 

怎樣使用 lsof?

在這篇文章裏,我會儘可能多地列舉我能想到的用例,來說明lsof的用法。讓我們從最簡單的例子開始(或許您已經知道了),由淺入深地展開吧。

 

列出所有打開的文件

# lsof

不帶任何參數執行lsof,就會列出所有進程打開的所有文件。

 

查找誰在使用某個文件

# lsof /path/to/file

以文件的路徑爲參數,lsof將會列出所有用這個文件的進程。

您也可以指定多個文件,lsof會列出所有使用這些文件的進程。

# lsof /path/to/file1 /path/to/file2

 

遞歸查找某個目錄下所有打開的文件

# lsof +D /usr/lib

帶上+D參數,lsof會在指定目錄及其下所有子目錄中查找找開的文件。注意這個操作效率比通常版本的grep低。

# lsof | grep '/usr/lib'

之所以慢,是因爲”+D”首先查找所有文件,然後再執行輸出。

 

列出某個用戶打開的所有文件

# lsof -u pkrumins

-u選項(認爲是user)限定輸出內容,只顯示pkrumins用戶打開的文件。您也可以同時限定多個用戶,用戶名之間以逗號爲分隔符(譯者注:逗號左右不要出現空格)

# lsof -u rms,root

這條命令會列出rms用戶和root用戶打開的所有文件。

另一種方式是多次使用-u選項,也能達到相同的目的:

# lsof -u rms -u root

 

按進程名查找打開的文件

# lsof -c apache

-c選項限定只列出進程名以apache打頭的進程所打開的文件。因此,可以不用寫:

# lsof | grep foo

而寫成更簡短的版本:

# lsof -c foo

事實上,您可以僅指定進程名的開頭部分進行查找:

# lsof -c apa

上面這條命令將列出所有名字以apa打頭的進程所打開的文件。

您還可以同時指定多個-c選項,以關聯多個進程:

# lsof -c apache -c python

這條命令將會列出apachepython打開的所有文件。


譯者注,對於多線程的進程來說,顯示TID(Task ID)有時是必要的,但是用“-c”選項缺省是不列出子任務的,這時可以加上"-K"(大寫)選項。

 

列出某個用戶或進程打開的所有文件

# lsof -u pkrumins -c apache

Lsof的選項可以關聯組合。缺省的關聯條件是或(OR)。這意味着上面這條命令輸出的內容爲:列出用戶pkrumins 或進程apache打開的所有文件。

 

列出某個用戶與某個進程打開的所有文件

# lsof -a -u pkrumins -c bash

注意-a選項。它把關聯組合的邏輯,由或(OR)變成與(AND)。所以上面這條命令輸出內容爲:pkrumins用戶所屬的,bash進程打開的所有文件。

 

列出除了root用戶之外,其它用戶打開的所有文件

# lsof -u ^root

注意root用戶名之前的^字符。它執行取反操作。所以這條命令輸出所有非root用戶打開的文件。

 

列出某個PID進程打開的所有文件

# lsof -p 1

 -p(聯想PID)選項,限定以進程的ID爲過濾條件。記住,您可以在一個-p選項中,用逗號分隔的方式指定多個PID,也可以多次指定-p選項:

# lsof -p 450,980,333

這條命令列出PID450980333的進程打開的所有文件。

 

列出某個PID之外,其它進程打開的所有文件

# lsof -p ^1

又碰到取反操作符^了。上面這條命令列出PID 1之外的進程打開的所有文件。

 

列出所有網絡連接

# lsof -i

通過-i選項lsof列出所有打開網絡套接字(TCPUDP)的進程。

 

列出所有TCP網絡連接

# lsof -i tcp

-i選項有幾個參數,tcp就是其中之一,它限定lsof僅顯示打開TCP套接字的進程。

 

列出所有UDP網絡連接

# lsof -i udp

-i選項的參數值改爲udp,就可以顯示打開UDP套接字的進程了。

 

查找誰佔用了某個端口

# lsof -i :25

-i選項的參數值改爲:25lsof就會查找佔用25端口的進程(包括TCPUDP)。您也可能指定端口服務名(詳見/etc/services)),而不指定具體端口號:

# lsof -i :smtp

 

查找誰佔用了某個UDP端口

# lsof -i udp:53

同樣,查找佔用的TCP端口命令爲:

# lsof -i tcp:80

 

查找某個用戶佔用的網絡端口

# lsof -a -u hacker -i

這裏,-a選項關聯組合了-u-i選項。上面使命列出了用戶hacker所佔用的網絡端口。

 

列出所有NFS(網絡文件系統)文件

# lsof -N

-N選項很容易記住,因爲它就是NFS

 

列出所有Unix socket文件

# lsof -U

-U選項很容易記住,因爲它就是UNIX

 

列出指定組ID的進程所打開的所有文件

# lsof -g 1234

進程組用於結進程進行邏輯分組。上面例子查找PGID1234的進程組成員打開的所有文件。

 

列出與某個特定文件描述符關聯的所有文件

# lsof -d 2

上面這條命令,列出所有打開文件描述符2的進程。您還可以指定文件描述符的範圍:

# lsof -d 0-2

這樣會列出與文件描述符012關聯的所有進程。

-d還選項還有許多特定參數可選,比方說mem,它列出內存映射文件:

# lsof -d mem

還有txt表示加載進內存,正在執行的進程:

# lsof -d txt

 

輸出佔用某些資源的進程PID

# lsof -t -i

-t選項,限定lsof僅輸出進程的PID。它與-i選項組合,就只顯示所有打開網絡連接的進程PID。這樣,如果要殺死所有使用網絡的進程就很容易了:

# kill -9 `lsof -t -i`

 

循環執行lsof

# lsof -r 1

-r選項,告訴lsof不斷地重複執行。參數值1表示重複週期爲1秒。這

# lsof -r 1 -u john -i -a



怎樣安裝lsof?

許多UNIX系統都預安裝了lsof。如果您的系統沒有,那麼到source下載源碼來安裝。

BSD系統有一個叫fstat的工具,實現的類似的功能。

完整的文檔在 man lsof可以找到,或者通過 lsof -h查看簡單的幫助。

快來體驗lsof的樂趣吧!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章