linux中lsof命令详解
参考:
简介
lsof(list open files)是⼀个列出当前系统打开⽂件的⼯具,在Unix中⼀切(包括⽹络套接⼝)都是⽂件。有趣的是,lsof也是有着最多开关的Linux/Unix命令之⼀。它有那么多的开关,它有许多选项⽀持使⽤-和+前缀。
选项描述
-a    列出打开⽂件存在的进程;
-c<;进程名>    列出指定进程所打开的⽂件;
-g    列出GID号进程详情;
-d<⽂件号>    列出占⽤该⽂件号的进程;
+d<⽬录>    列出⽬录下被打开的⽂件;
+D<⽬录>    递归列出⽬录下被打开的⽂件;
-n<⽬录>    列出使⽤NFS的⽂件;
-i<;条件>    列出符合条件的进程。(4、6、协议、:端⼝、 @ip )
-p<;进程号>    列出指定进程号所打开的⽂件;
-u    列出UID号进程详情;
-h    显⽰帮助信息;
-v    显⽰版本信息。
关键字段含义
lsof
COMMAND    PID  TID    USER  FD      TYPE            DEVICE  SIZE/OFF      NODE NAME
systemd      1          root  cwd      DIR            253,1  4096          2 /
systemd      1          root  rtd      DIR              253,1  4096
FD⽂件描述符列表
cwd:表⽰current work dirctory,即:应⽤程序的当前⼯作⽬录,这是该应⽤程序启动的⽬录,除⾮它本⾝对这个⽬录进⾏更改
txt:该类型的⽂件是程序代码,如应⽤程序⼆进制⽂件本⾝或共享库,如上列表中显⽰的 /sbin/init 程序
lnn:library references (AIX)(库引⽤);
er:FD information error (see NAME column)(fd信息错误);
jld:jail directory (FreeBSD)(监控⽬录);
ltx:shared library text (code and data)(共享库⽂本);
mxx :hex memory-mapped type number xx(⼗六进制内存映射类型号xx);
m86:DOS Merge mapped file(DOS合并映射⽂件);
mem:memory-mapped file(内存映射⽂件);
mmap:memory-mapped device(内存映射设备);
pd:parent directory(⽗⽬录);
rtd:root directory(跟⽬录);
tr:kernel trace file (OpenBSD)(内核跟踪⽂件);
v86 VP/ix mapped file(VP/IX映射⽂件);
0:表⽰标准输出
1:表⽰标准输⼊
2:表⽰标准错误
⼀般在标准输出、标准错误、标准输⼊后还跟着⽂件状态模式:
u:表⽰该⽂件被打开并处于读取/写⼊模式。
r:表⽰该⽂件被打开并处于只读模式。
w:表⽰该⽂件被打开并处于。
空格:表⽰该⽂件的状态模式为unknow,且没有锁定。
-:表⽰该⽂件的状态模式为unknow,且被锁定。
同时在⽂件状态模式后⾯,还跟着相关的锁:
N:for a Solaris NFS lock of unknown type(对于未知类型的Solaris NFS锁);
r:for read lock on part of the file(⽤于对⽂件的⼀部分进⾏读取锁定);
R:for a read lock on the entire file(整个⽂件的读取锁定);
w:for a write lock on part of the file;(⽂件的部分写锁)
W:for a write lock on the entire file;(整个⽂件的写锁)
u:for a read and write lock of any length(对于任意长度的读写锁);
U:for a lock of unknown type(对于未知类型的锁);
x:for an SCO OpenServer Xenix lock on part of the file(对于⽂件的sco openserver xenix锁); X:for an SCO OpenServer Xenix lock on the entire file(对于整个⽂件的sco openserver xenix锁); space:if there is no lock(如果没有锁).
2.1.2 ⽂件类型:
DIR:表⽰⽬录。
CHR:表⽰字符类型。
BLK:块设备类型。
UNIX: UNIX 域套接字。
FIFO:先进先出 (FIFO) 队列。
IPv4:⽹际协议 (IP) 套接字。
DEVICE:指定磁盘的名称
SIZE:⽂件的⼤⼩
NODE:索引节点(⽂件在磁盘上的标识)
NAME:打开⽂件的确切名称
lsof使⽤实例
1.列出所有打开的⽂件:
lsof
备注: 如果不加任何参数,就会打开所有被打开的⽂件,建议加上⼀下参数来具体定位2. 查看谁正在使⽤某个⽂件
lsof access_nginx.log
3.显⽰⽬录下被进程开启的⽂件
lsof +d /usr/local/
4. ⽐使⽤+D选项,遍历查看某个⽬录的所有⽂件信息 的⽅法
lsof +D /usr/local/
5. 列出某个⽤户打开的⽂件信息
lsof  -u username
备注: -u 选项,u其实是user的缩写
6. 列出某个程序所打开的⽂件信息
lsof -c mysql
备注: -c 选项将会列出所有以mysql开头的程序的⽂件,其实你也可以写成lsof | grep mysql,但是第⼀种⽅法明显⽐第⼆种⽅法要少打⼏个字符了
7. 列出多个程序多打开的⽂件信息
linux查看目录命令
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. 根据⽂件描述列出对应的⽂件信息,显⽰使⽤fd为4的进程
lsof -d 4
23. 根据⽂件描述范围列出⽂件信息
lsof -d 2-3
场景⼀ 有时可以通过lsof恢复删除的⽂件
原理:
当进程打开了某个⽂件时,只要该进程保持打开该⽂件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道⽂件已经被删除,它仍然可以向打开该⽂件时提供给它的⽂件描述符进⾏读取和写⼊。除了该进程之外,这个⽂件是不可见的,因为已经删除了其相应的⽬录索引节点。
在/proc ⽬录下,其中包含了反映内核和进程树的各种⽂件。/proc⽬录挂载的是在内存中所映射的⼀块区域,所以这些⽂件和⽬录并不存在于磁盘中,因此当我们对这些⽂件进⾏读取和写⼊时,实际上是在从内存中获取相关信息。⼤多数与 lsof 相关的信息都存储于以进程的PID 命名的⽬录中,即 /proc/20996 中包含的是 PID 为 20996的进程的信息。每个进程⽬录中存在着各种⽂件,它们可以使得应⽤程序简单地了解进程的内存空间、⽂件描述符列表、指向磁盘上的⽂件的符号链接和其他系统信息。lsof 程序使⽤该信息和其他关于内核内部状态的信息来产⽣其输出。
实践:
当我们不⼩⼼误删了某个⽂件⽐如 access_nginx.log,只要这个时候系统中还有进程正在访问该⽂件,那么我们就可以通过lsof从/proc⽬录下恢复该⽂件的内容。
恢复的⽅法如下:
⾸先使⽤lsof来查看当前是否有进程打开access_nginx.log⽂件,如下:
lsof |grep -E 'FD|access_nginx'
COMMAND    PID  TID    USER  FD      TYPE            DEVICE  SIZE/OFF      NODE NAME
nginx    20996          root  14w      REG              253,1    351016      49298 /data/wwwlogs/access_nginx.log (deleted)
nginx    29177          www  14w      REG              253,1    351016      49298 /data/wwwlogs/access_nginx.log (deleted)
nginx    29178          www  14w      REG              253,1    351016      49298 /data/wwwlogs/access_nginx.log (deleted)
PID 20996 打开⽂件的⽂件描述符为14w。状态为deleted。因此我们可以在 /proc/20996/fd/14(fd下的每个以数字命名的⽂件表⽰进程对应的⽂件描述符)中查看相应的信息,如下:
head -n 10 /proc/20996/fd/14
182.254.52.17 - - [28/May/2020:04:25:16 +0800] "GET 154.8.236.121/?id%3D17 HTTP/1.1" 200 4743 "-
" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0"
60.191.52.254 - - [28/May/2020:04:49:26 +0800] "HEAD 112.124.42.80:63435/ HTTP/1.1" 200 0 "-
" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36"
cat /proc/20996/fd/14 > access_nginx.log
恢复完毕
场景⼆ too many open files报错,查看哪些程序打开了很多⽂件
⽹上很多介绍⽤下⾯命令,其实是不准确得
lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|head -n 5
应该⽤下⾯得命令
查看哪个进程使⽤的fd最多:
find /proc -print | grep -P '/proc/\d+/fd/'| awk -F '/' '{print $3}' | uniq -c | sort -rn | head
查看fd使⽤总数:
cat /proc/sys/fs/file-nr
或者(结果多的时候运⾏需要⼀段时间)
find /proc -print | grep -P '/proc/\d+/fd/'| wc -l

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。