Linux 命令神器:lsof

做者:西華子
連接:https://www.jianshu.com/p/a3aa6b01b2e1
來源:簡書
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。css



lsof是系統管理/安全的尤伯工具。將這個工具稱之爲lsof真實名副其實,由於它是指「列出打開文件(lists openfiles)」。而有一點要切記,在Unix中一切(包括網絡套接口)都是文件。html

有趣的是,lsof也是有着最多開關的Linux/Unix命令之一。它有那麼多的開關,它有許多選項支持使用-和+前綴。linux

1.  usage:  [-?abhlnNoOPRstUvV]  [+|-c c]  [+|-d s]  [+D D]  [+|-f[cgG]]
2.  [-F [f]]  [-g [s]]  [-i [i]]  [+|-L [l]]  [+|-M]  [-o [o]]
3.  [-p s]  [+|-r [t]]  [-S [t]]  [-T [t]]  [-u s]  [+|-w]  [-x [fl]]  [--]  [names]

正如你所見,lsof有着實在是使人驚訝的選項數量。你可使用它來得到你係統上設備的信息,你能經過它瞭解到指定的用戶在指定的地點正在碰什麼東西,或者甚至是一個進程正在使用什麼文件或網絡鏈接。c++

對於我,lsof替代了netstat和ps的所有工做。它能夠帶來那些工具所能帶來的一切,並且要比那些工具多得多。那麼,讓咱們來看看它的一些基本能力吧:安全

關鍵選項

理解一些關於lsof如何工做的關鍵性東西是很重要的。最重要的是,當你給它傳遞選項時,默認行爲是對結果進行「或」運算。所以,若是你正是用-i來拉出一個端口列表,同時又用-p來拉出一個進程列表,那麼默認狀況下你會得到二者的結果。ruby

下面的一些其它東西須要牢記:bash

  • 默認 : 沒有選項,lsof列出活躍進程的全部打開文件網絡

  • 組合 : 能夠將選項組合到一塊兒,如-abc,但要小心哪些選項須要參數ssh

  • -a : 結果進行「與」運算(而不是「或」)tcp

  • -l : 在輸出顯示用戶ID而不是用戶名

  • -h : 得到幫助

  • -t : 僅獲取進程ID

  • -U : 獲取UNIX套接口地址

  • -F : 格式化輸出結果,用於其它命令。能夠經過多種方式格式化,如-F pcfn(用於進程id、命令名、文件描述符、文件名,並以空終止)

獲取網絡信息

正如我所說的,我主要將lsof用於獲取關於系統怎麼和網絡交互的信息。這裏提供了關於此信息的一些主題:

使用-i顯示全部鏈接

有些人喜歡用netstat來獲取網絡鏈接,可是我更喜歡使用lsof來進行此項工做。結果以對我來講很直觀的方式呈現,我僅僅只需改變個人語法,就能夠經過一樣的命令來獲取更多信息。

語法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]

1.  #  lsof  -i

3.  COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
4.  dhcpcd 6061 root 4u  IPv4  4510 UDP *:bootpc
5.  sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)6.  sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)

使用-i 6僅獲取IPv6流量

1.  #  lsof  -i 6

僅顯示TCP鏈接(同理可得到UDP鏈接)

你也能夠經過在-i後提供對應的協議來僅僅顯示TCP或者UDP鏈接信息。

1.  #  lsof  -iTCP

3.  COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
4.  sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)5.  sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)

使用-i:port來顯示與指定端口相關的網絡信息

或者,你也能夠經過端口搜索,這對於要找出什麼阻止了另一個應用綁定到指定端口實在是太棒了。

1.  #  lsof  -i :22

3.  COMMAND  PID USER   FD   TYPE DEVICE SIZE NODE NAME
4.  sshd  7703 root 3u  IPv6  6499 TCP *:ssh  (LISTEN)5.  sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->192.168.1.5:49901  (ESTABLISHED)

使用@host來顯示指定到指定主機的鏈接

這對於你在檢查是否開放鏈接到網絡中或互聯網上某個指定主機的鏈接時十分有用。

1.  #  lsof  -i@172.16.12.5

3.  sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->172.16.12.5:49901  (ESTABLISHED)

使用@host:port顯示基於主機與端口的鏈接

你也能夠組合主機與端口的顯示信息。

1.  #  lsof  -i@172.16.12.5:223.  sshd  7892 root 3u  IPv6  6757 TCP 10.10.1.5:ssh->172.16.12.5:49901  (ESTABLISHED)

找出監聽端口

找出正等候鏈接的端口。

1.  #  lsof  -i -sTCP:LISTEN

你也能夠grep 「LISTEN」來完成該任務。

1.  #  lsof  -i |  grep  -i LISTEN3.  iTunes 400 daniel 16u  IPv4  0x4575228  0t0 TCP *:daap (LISTEN)

找出已創建的鏈接

你也能夠顯示任何已經鏈接的鏈接。

1.  #  lsof  -i -sTCP:ESTABLISHED

你也能夠經過grep搜索「ESTABLISHED」來完成該任務。

1.  #  lsof  -i |  grep  -i ESTABLISHED3.  firefox-b 169 daniel 49u  IPv4  0t0 TCP 1.2.3.3:1863->1.2.3.4:http (ESTABLISHED)

用戶信息

你也能夠獲取各類用戶的信息,以及它們在系統上正幹着的事情,包括它們的網絡活動、對文件的操做等。

使用-u顯示指定用戶打開了什麼

1.  #  lsof  -u daniel

3.  -- snipped --
4.  Dock  155 daniel  txt REG 14,2  2798436  823208  /usr/lib/libicucore.A.dylib
5.  Dock  155 daniel  txt REG 14,2  1580212  823126  /usr/lib/libobjc.A.dylib
6.  Dock  155 daniel  txt REG 14,2  2934184  823498  /usr/lib/libstdc++.6.0.4.dylib
7.  Dock  155 daniel  txt REG 14,2  132008  823505  /usr/lib/libgcc_s.1.dylib
8.  Dock  155 daniel  txt REG 14,2  212160  823214  /usr/lib/libauto.dylib
9.  -- snipped --

使用-u user來顯示除指定用戶之外的其它全部用戶所作的事情

1.  #  lsof  -u ^daniel

3.  -- snipped --
4.  Dock  155 jim  txt REG 14,2  2798436  823208  /usr/lib/libicucore.A.dylib
5.  Dock  155 jim  txt REG 14,2  1580212  823126  /usr/lib/libobjc.A.dylib
6.  Dock  155 jim  txt REG 14,2  2934184  823498  /usr/lib/libstdc++.6.0.4.dylib
7.  Dock  155 jim  txt REG 14,2  132008  823505  /usr/lib/libgcc_s.1.dylib
8.  Dock  155 jim  txt REG 14,2  212160  823214  /usr/lib/libauto.dylib
9.  -- snipped --

殺死指定用戶所作的一切事情

能夠消滅指定用戶運行的全部東西,這真不錯。

1.  #  kill  -9  `lsof -t -u daniel`

命令和進程

能夠查看指定程序或進程由什麼啓動,這一般會頗有用,而你可使用lsof經過名稱或進程ID過濾來完成這個任務。下面列出了一些選項:

使用-c查看指定的命令正在使用的文件和網絡鏈接

1.  #  lsof  -c syslog-ng

3.  COMMAND    PID USER   FD   TYPE     DEVICE    SIZE       NODE NAME
4.  syslog-ng 7547 root  cwd    DIR 3,3  4096  2  /
5.  syslog-ng 7547 root  rtd    DIR 3,3  4096  2  /
6.  syslog-ng 7547 root  txt    REG 3,3  113524  1064970  /usr/sbin/syslog-ng
7.  -- snipped --

使用-p查看指定進程ID已打開的內容

1.  #  lsof  -p 10075

3.  -- snipped --
4.  sshd  10068 root  mem    REG 3,3  34808  850407  /lib/libnss_files-2.4.so
5.  sshd  10068 root  mem    REG 3,3  34924  850409  /lib/libnss_nis-2.4.so
6.  sshd  10068 root  mem    REG 3,3  26596  850405  /lib/libnss_compat-2.4.so
7.  sshd  10068 root  mem    REG 3,3  200152  509940  /usr/lib/libssl.so.0.9.7
8.  sshd  10068 root  mem    REG 3,3  46216  510014  /usr/lib/liblber-2.3
9.  sshd  10068 root  mem    REG 3,3  59868  850413  /lib/libresolv-2.4.so
10.  sshd  10068 root  mem    REG 3,3  1197180  850396  /lib/libc-2.4.so
11.  sshd  10068 root  mem    REG 3,3  22168  850398  /lib/libcrypt-2.4.so
12.  sshd  10068 root  mem    REG 3,3  72784  850404  /lib/libnsl-2.4.so
13.  sshd  10068 root  mem    REG 3,3  70632  850417  /lib/libz.so.1.2.3
14.  sshd  10068 root  mem    REG 3,3  9992  850416  /lib/libutil-2.4.so
15.  -- snipped --

-t選項只返回PID

1.  #  lsof  -t -c Mail

3.  350

文件和目錄

經過查看指定文件或目錄,你能夠看到系統上全部正與其交互的資源——包括用戶、進程等。

顯示與指定目錄交互的全部一切

1.  #  lsof  /var/log/messages/

3.  COMMAND    PID USER   FD   TYPE DEVICE   SIZE   NODE NAME
4.  syslog-ng 7547 root 4w REG 3,3  217309  834024  /var/log/messages

顯示與指定文件交互的全部一切

1.  #  lsof  /home/daniel/firewall_whitelist.txt

高級用法

tcpdump相似,當你開始組合查詢時,它就顯示了它強大的功能。

顯示daniel鏈接到1.1.1.1所作的一切

1.  #  lsof  -u daniel -i @1.1.1.1

3.  bkdr 1893 daniel 3u  IPv6  3456 TCP 10.10.1.10:1234->1.1.1.1:31337  (ESTABLISHED)

同時使用-t和-c選項以給進程發送 HUP 信號

1.  #  kill  -HUP `lsof -t -c sshd`

lsof +L1顯示全部打開的連接數小於1的文件

這一般(當不老是)表示某個***者正嘗試經過刪除文件入口來隱藏文件內容。

1.  #  lsof  +L1

3.  (hopefully nothing)

顯示某個端口範圍的打開的鏈接

1.  #  lsof  -i @fw.google.com:2150=2180

結尾

本入門教程只是管窺了lsof功能的一斑,要查看完整參考,運行man lsof命令或查看在線版本。但願本文對你有所助益,也隨時歡迎你的評論和指正

資源

本文由 Daniel Miessler撰寫,首次在他博客上貼出

通常root用戶才能執行lsof命令,普通用戶能夠看見/usr/sbin/lsof命令,
可是普通用戶執行會顯示「permission denied」

我總結一下lsof指令的用法:

lsof abc.txt 顯示開啓文件abc.txt的進程

lsof -i :22 知道22端口如今運行什麼程序

lsof -c abc 顯示abc進程如今打開的文件

lsof -g gid 顯示歸屬gid的進程狀況

lsof +d /usr/local/ 顯示目錄下被進程開啓的文件

lsof +D /usr/local/ 同上,可是會搜索目錄下的目錄,時間較長

lsof -d 4 顯示使用fd爲4的進程  www.2cto.com

lsof -i 用以顯示符合條件的進程狀況

語法: lsof -i[46] [protocol][@hostname|hostaddr][:service|port]

46 --> IPv4 or IPv6

protocol --> TCP or UDP

hostname --> Internet host name

hostaddr --> IPv4位置

service --> /etc/service中的 service name (能夠不僅一個)

port --> 端口號 (能夠不僅一個)

例子: TCP:25 - TCP and port 25

@1.2.3.4 - Internet IPv4 host address 1.2.3.4

tcp@ohaha.ks.edu.tw:ftp - TCP protocol hosthaha.ks.edu.tw service name:ftp

lsof -n 不將IP轉換爲hostname,缺省是不加上-n參數

例子: lsof -i tcp@ohaha.ks.edu.tw:ftp -n

lsof -p 12 看進程號爲12的進程打開了哪些文件

lsof +|-r [t] 控制lsof不斷重複執行,缺省是15s刷新

-r,lsof會永遠不斷的執行,直到收到中斷信號

+r,lsof會一直執行,直到沒有檔案被顯示

例子:不斷查看目前ftp鏈接的狀況:lsof -i tcp@ohaha.ks.edu.tw:ftp -r

lsof -s 列出打開文件的大小,若是沒有大小,則留下空白

lsof -u username 以UID,列出打開的文件  www.2cto.com

關注:
進程調試命令:truss、strace和ltrace
進程沒法啓動,軟件運行速度忽然變慢,程序的"SegmentFault"等等都是讓每一個Unix系統用戶頭痛的問題,而這些問題均可以經過使用truss、strace和ltrace這三個經常使用的調試工具來快速診斷軟件的"疑難雜症"。

做者:西華子連接:https://www.jianshu.com/p/a3aa6b01b2e1來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

相關文章
相關標籤/搜索