首页 > 代码库 > lsof命令

lsof命令


lsof命令可以列出当前系统打开的文件描述符,由哪个进程打开了哪个文件等信息。因为Linux系统上一切皆文件,所以无论是普通的文件访问还是网络通信都会用到文件描述符或者说都是一个文件。

技术分享

列名说明
COMMAND进程的名称
PID进程PID号
USER进程的所有者
FD文件描述符,应用程序通过文件描述符识别文件
TYPE

文件类型:

               REG:文件

               DIR:目录

               CHR:字符设备

               BLK:块设备

DEVICE
设备名称
SIZE/OFF
文件大小
NODE
索引节点
NAME

常用参数:

参数
说明
-c COMMAND显示指定COMMAND列中的进程打开的文件
-c -p PID显示制定进程号打开的文件
-u USERNAME显示所属用户进程打开的文件
-g GID显示所属GID进程打开的文件
-d FD显示指定的文件描述符
-i显示网络进程打开的文件
-i PORT显示指定端口打开的文件
+d /DIR显示指定目录被哪个进程打开
+D /DIR
功能同上,但是会搜索目录下所有的目录
-n
显示IP地址而不是主机名

举例说明:

显示22端口被哪个进程占用以及打开的文件描述符

lsof -i:22 -n

技术分享

显示Nginx用户打开哪些文件

lsof -u nginx

技术分享

显示指定文件被哪些进程所打开

lsof /var/log/nginx/error.log

技术分享

显示指定目录下由哪些文件被打开

注意:+d的效果,下面两个命令一样,但是结果不同,说明+d参数不搜索子目录

lsof +d /var/log/

技术分享如果要想搜索子目录就要使用+D参数,但是搜索比较消耗时间

lsof +D /var/

技术分享

恢复删除文件:

下面的方式只是在特定场景下可以使用。比如删除日志文件,但是磁盘空间没有释放,因为进程还在使用那个文件,虽然你在路径中找不到了,这种情况下你删除文件,其实该文件还是存在的,因为进程不通过文件名称找文件,而是文件描述符,所以对于进程来说它并不知道文件被删除了。

另外删除文件其实只是切断了INODE与块的关系,在位图中标识出该块可用,数据其实还在。如果一个文件正在被进程使用,你删除了的话那么位图是不会更新的,所以内核认为该文件没有删除,所以可用空间不会增长。

举例说明:Nginx的访问日志,我FOR循环2万次不断访问,这样Nginx的日志文件就会不断写入,在写入期间,我删除该文件,然后找回。

首先查看Nginx的日志文件都由哪些进程来使用

技术分享不断监控其大小变化

watch -n 1 du -sh *

技术分享

循环访问开始,日志出现了增长

技术分享

删除文件,并没有得到任何提示

技术分享

再来查看监控大小这边,提示文件找不到了

技术分享

查看文件描述符信息,有了一个(deleted)的标签

//通过这个命令就可以查找被程序打开且被删除的文件
lsof | grep deleted

技术分享通过文件描述符查看文件信息

技术分享

我们知道/proc是个伪文件系统,内容都在内存中,我们这时候通过查看命令就可以看这个文件描述符所指向的内容

head -n 100 /proc/94429/fd/5

技术分享

既然可以看其实就可以保存,因为Nginx我这里启动了2个进程,你只需要把所有进程对应的文件描述符通过下面的访问写入到一个文件,就把之前的内容都找回了。

cat /proc/94429/fd/5 >> /var/log/nginx/access_restore.log

技术分享

本文出自 “小恶魔的家” 博客,请务必保留此出处http://littledevil.blog.51cto.com/9445436/1909353

lsof命令