lsof 是 linux 下的一個很是實用的系統級的監控、診斷工具。
它的意思是 List Open Files,很容易你就記住了它是 「ls + of」的組合~
它能夠用來列出被各類進程打開的文件信息,記住:linux 下 「一切皆文件」,
包括但不限於 pipes, sockets, directories, devices, 等等。
所以,使用 lsof,你能夠獲取任何被打開文件的各類信息。html
lsof打開的文件能夠是:mysql
1.普通文件linux
2.目錄nginx
3.網絡文件系統的文件sql
4.字符或設備文件ubuntu
5.(函數)共享庫windows
6.管道,命名管道bash
7.符號連接網絡
8.網絡文件(例如:NFS file、網絡socket,unix域名socket)session
9.還有其它類型的文件,等等
只需輸入 lsof 就能夠生成大量的信息,由於 lsof 須要訪問核心內存和各類文件,因此必須以 root 用戶的身份運行它纔可以充分地發揮其功能。
lsof 的示例輸出:
root@ubuntu:~# lsof |more COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME init 1 root cwd DIR 8,1 4096 2 / init 1 root rtd DIR 8,1 4096 2 / init 1 root txt REG 8,1 167192 1048582 /sbin/init init 1 root mem REG 8,1 52120 398011 /lib/x86_64-linux-gnu/libnss_files-2.15.so init 1 root mem REG 8,1 47680 393442 /lib/x86_64-linux-gnu/libnss_nis-2.15.so init 1 root mem REG 8,1 97248 398020 /lib/x86_64-linux-gnu/libnsl-2.15.so init 1 root mem REG 8,1 35680 398021 /lib/x86_64-linux-gnu/libnss_compat-2.15.so
每行顯示一個打開的文件,若不指定條件默認將顯示全部進程打開的全部文件。
lsof輸出各列信息的意義以下:
COMMAND:進程的名稱
PID:進程標識符
PPID:父進程標識符(須要指定-R參數)
USER:進程全部者
PGID:進程所屬組(須要指定-R參數)
FD:文件描述符,應用程序經過文件描述符識別該文件。如cwd、txt等
(1)cwd:表示current work dirctory,即:應用程序的當前工做目錄,這是該應用程序啓動的目錄,除非它自己對這個目錄進行更改 (2)txt :該類型的文件是程序代碼,如應用程序二進制文件自己或共享庫,如上列表中顯示的 /sbin/init 程序 (3)lnn:library references (AIX); (4)er:FD information error (see NAME column); (5)jld:jail directory (FreeBSD); (6)ltx:shared library text (code and data); (7)mxx :hex memory-mapped type number xx. (8)m86:DOS Merge mapped file; (9)mem:memory-mapped file; (10)mmap:memory-mapped device; (11)pd:parent directory; (12)rtd:root directory; (13)tr:kernel trace file (OpenBSD); (14)v86 VP/ix mapped file; (15)0:表示標準輸出 (16)1:表示標準輸入 (17)2:表示標準錯誤
通常在標準輸出、標準錯誤、標準輸入後還跟着文件狀態模式:r、w、u等
(1)u:表示該文件被打開並處於讀取/寫入模式 (2)r:表示該文件被打開並處於只讀模式 (3)w:表示該文件被打開並處於 (4)空格:表示該文件的狀態模式爲unknow,且沒有鎖定 (5)-:表示該文件的狀態模式爲unknow,且被鎖定
同時在文件狀態模式後面,還跟着相關的鎖
(1)N:for a Solaris NFS lock of unknown type; (2)r:for read lock on part of the file; (3)R:for a read lock on the entire file; (4)w:for a write lock on part of the file;(文件的部分寫鎖) (5)W:for a write lock on the entire file;(整個文件的寫鎖) (6)u:for a read and write lock of any length; (7)U:for a lock of unknown type; (8)x:for an SCO OpenServer Xenix lock on part of the file; (9)X:for an SCO OpenServer Xenix lock on the entire file; (10)space:if there is no lock.
TYPE:文件類型,如DIR、REG等
常見的文件類型
(1)DIR:表示目錄 (2)CHR:表示字符類型 (3)BLK:塊設備類型 (4)UNIX: UNIX 域套接字 (5)FIFO:先進先出 (FIFO) 隊列 (6)IPv4:網際協議 (IP) 套接字
DEVICE:指定磁盤的名稱
SIZE:文件的大小
NODE:索引節點(文件在磁盤上的標識)
NAME:打開文件的確切名稱
備註:
初始打開每一個應用程序時,都具備三個文件描述符,從 0 到 2,分別表示標準輸入、輸出和錯誤流。因此大多數應用程序所打開的文件的 FD 都是從 3 開始。
二、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[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 --> 端口號 (能夠不止一個)
2.1 監控打開的文件、設備
查看文件、設備被哪些進程佔用
root@ubuntu:~# lsof /dev/tty1 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME getty 1114 root 0u CHR 4,1 0t0 5875 /dev/tty1 getty 1114 root 1u CHR 4,1 0t0 5875 /dev/tty1
2.2 監控文件系統
指定目錄、掛載點,能夠看到有哪些進程打開了其下的文件:
root@ubuntu:~# lsof /run/ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd-u 393 root 5u REG 0,16 8 9564 /run/udev/queue.bin cron 883 root 3u REG 0,16 4 9340 /run/crond.pid vmtoolsd 1132 root 4w REG 0,16 5 10481 /run/vmtoolsd.pid sshd 1354 ssp 7w FIFO 0,16 0t0 11159 /run/systemd/sessions/1.ref 。。。。。。。。
這在 umount 某個文件系統失敗時很是有用(一般會報該 FS is busy)。
列出某個目錄(掛載點 如 /home 也行)下被打開的文件:
lsof +d /usr/local/
顯示目錄下被進程開啓的文件
lsof +D /usr/local/ 同上,可是會搜索目錄下的目錄,時間較長
root@ubuntu:~# lsof +D /var/log/ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME init 1 root 11w REG 8,1 293 527702 /var/log/upstart/systemd-logind.log rsyslogd 568 syslog 1w REG 8,1 500562 527477 /var/log/syslog mysqld 934 mysql 1w REG 8,1 9311 525582 /var/log/mysql/error.log nginx 1026 www-data 5w REG 8,1 6213 525610 /var/log/nginx/error.log 。。。。
列出被指定進程名打開的文件:
lsof -c abc
顯示
abc
進程如今打開的文件
root@ubuntu:~# lsof -c ssh -c init COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME init 1 root cwd DIR 8,1 4096 2 / sshd 861 root cwd DIR 8,1 4096 2 / 。。。。。。。。
2.3 監控進程
指定進程號,能夠查看該進程打開的文件:
root@ubuntu:~# ps -ef |grep nginx root 1022 1 0 14:19 ? 00:00:00 nginx: master process /usr/sbin/nginx www-data 1023 1022 0 14:19 ? 00:00:00 nginx: worker process www-data 1024 1022 0 14:19 ? 00:00:00 nginx: worker process root@ubuntu:~# lsof -p 1022 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1022 root cwd DIR 8,1 4096 2 / nginx 1022 root rtd DIR 8,1 4096 2 / nginx 1022 root txt REG 8,1 873176 924436 /usr/sbin/nginx nginx 1022 root mem REG 8,1 47712 399039 /lib/x86_64-linux-gnu/libnss_files-2.19.so 。。。。。。
當你想要殺掉某個用戶全部打開的文件、設備,你能夠這樣:.
kill -9 `lsof -t -u nginx`
此處 -t 的做用是單獨的列出 進程 id 這一列。-u 爲制定用戶
關於殺死進程的 4 種方式,請參考:
http://www.thegeekstuff.com/2009/12/4-ways-to-kill-a-process-kill-killall-pkill-xkill/
2.4 監控網絡
查看指定端口有哪些進程在使用(lsof -i 列出全部的打開的網絡鏈接):
root@ubuntu:~# lsof -i :22 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 861 root 3u IPv4 9400 0t0 TCP *:ssh (LISTEN) sshd 1335 root 3u IPv4 11111 0t0 TCP 10.18.98.61:ssh->10.18.96.34:59622 (ESTABLISHED)
列出被某個進程打開全部的網絡文件:
root@ubuntu:~# lsof -i -a -p 1022 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1022 root 7u IPv4 9501 0t0 TCP *:http (LISTEN) nginx 1022 root 8u IPv6 9502 0t0 TCP *:http (LISTEN) 或者 root@ubuntu:~# lsof -i -a -c nginx COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1022 root 7u IPv4 9501 0t0 TCP *:http (LISTEN) nginx 1023 www-data 7u IPv4 9501 0t0 TCP *:http (LISTEN)
-c選項限定只列出以nginx開頭的進程打開的文件
-a參數能夠將多個選項的組合條件由或變爲與 (and)
列出全部 tcp、udp 鏈接:
root@ubuntu:~# lsof -i tcp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 861 root 3u IPv4 9400 0t0 TCP *:ssh (LISTEN) mysqld 934 mysql 10u IPv4 10600 0t0 TCP localhost:mysql (LISTEN) root@ubuntu:~# lsof -i udp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME dhclient 714 root 6u IPv4 9073 0t0 UDP *:bootpc dhclient 714 root 20u IPv4 8993 0t0 UDP *:28931 dhclient 714 root 21u IPv6 8994 0t0 UDP *:5872
列出全部 NFS 文件:
root@ubuntu:~# lsof -N -u ssp –a
-N 列出全部NFS(網絡文件系統)文件 (-N就對應NFS)
查看指定網口有哪些進程在使用:(@)
root@ubuntu:~# lsof -i @10.18.98.61 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1335 root 3u IPv4 11111 0t0 TCP 10.18.98.61:ssh->10.18.96.34:59622 (ESTABLISHED) sshd 1354 ssp 3u IPv4 11111 0t0 TCP 10.18.98.61:ssh->10.18.96.34:59622 (ESTABLISHED)
3、更多使用技巧
3.1 監控用戶
查看指定用戶打開的文件(lsof -u ^ssp 能夠排除某用戶):
root@ubuntu:~# lsof -u ssp COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1354 ssp cwd DIR 8,1 4096 2 / sshd 1354 ssp rtd DIR 8,1 4096 2 / sshd 1354 ssp txt REG 8,1 766784 930638 /usr/sbin/sshd sshd 1354 ssp DEL REG 0,4 11142 /dev/zero
3.2 監控應用程序
查看指定程序打開的文件:
-c選項限定只列出以nginx開頭的進程打開的文件
root@ubuntu:~# lsof -c nginx (也能夠 ng ngin 等等) COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 1022 root cwd DIR 8,1 4096 2 / nginx 1022 root rtd DIR 8,1 4096 2 / nginx 1022 root txt REG 8,1 873176 924436 /usr/sbin/nginx nginx 1022 root mem REG 8,1 97296 399048 /lib/x86_64-linux-gnu/libnsl-2.19.so
4、命令模式技巧
4.1 組合邏輯查詢條件
只有多個查詢條件都知足, 用 "-a" 參數,默認是 -o 。
root@ubuntu:~# lsof -a -u ssp -c ssh COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 1354 ssp cwd DIR 8,1 4096 2 / sshd 1354 ssp rtd DIR 8,1 4096 2 / sshd 1354 ssp txt REG 8,1 766784 930638 /usr/sbin/sshd sshd 1354 ssp DEL REG 0,4 11142 /dev/zero sshd 1354 ssp mem REG 8,1 14464 393516 /lib/x86_64-linux-gnu/security/pam_env.so
4.2 lsof 命令的重複執行模式:
基於給定的參數延時多少秒重複執行 lsof
+r 表示 當沒有文件被打開的時候,repeat mode 將自行結束。
-r 表示 無論文件是否存在或者被打開,它都將執行,直到你中斷它。
每一個循環的輸出使用 ‘=======’ 作分隔符,你也能夠用 ‘-r’ | ‘+r’ 指定延時時間。
root@ubuntu:~# lsof -u ssp -c nginx -a -r1 (1秒循環一次,知道用戶本身中斷) ======= ======= root@ubuntu:~# lsof -u ssp -c nginx -a +r1 (1秒循環一次,若是沒有輸出的話就結束)
5、最後的技巧
關於磁盤空間告警 df -h --max=1 與 du -hx --max=1 顯示不一致的問題,
最多見的的仍是下面這種狀況:
lsof|grep -i delete
看看被刪除的文件:有些刪了文件,可是進程沒 reload,那些空間仍是佔用的,你能夠理解爲相似 windows 下的進程句柄沒釋放的概念吧~ 只是 windows 下若是有文件被進程使用,你通常是刪不掉的,而 linux 雖然不作刪除限制,但卻要等到進程使用完文件才能徹底釋放,以防止進程奔潰,這是操做系統對資源的管理差別吧~
例如 nginx 會有不少臨時文件佔用了 /tmp 目錄,刪掉後,依然佔用着空間,
此時你能夠:
pkill -9 nginx && /etc/init.d/nginx restart
6、refer:
使用 lsof 查找打開的文件
http://www.ibm.com/developerworks/cn/aix/library/au-lsof.html
15 Linux lsof Command Examples (Identify Open Files)
http://www.thegeekstuff.com/2012/08/lsof-command-examples/
實用的系統工具之 lsof