Chinaunix首页 | 论坛 | 博客
  • 博客访问: 680915
  • 博文数量: 209
  • 博客积分: 26
  • 博客等级: 民兵
  • 技术积分: 326
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-21 09:29
文章分类

全部博文(209)

文章存档

2015年(6)

2014年(40)

2013年(154)

2012年(11)

我的朋友

分类: LINUX

2013-08-16 17:23:08

原文地址:lsof 作者:scq2099yt

一、基本语法
        lsof(list open files)是一个列出当前系统打开文件的工具。在Linux平台下,世间万物皆文件。在命令行下输入lsof即可显示系统打开的文件信息列表,默认情况下将显示所有简称打开的所有文件,每行显示一个打开的文件,由于信息比较多所以可以用管道重定向后分页显示:
        
        从上图可以看出,lsof会输出很多列表,具体含义如下:
        COMMAND:进程名称
        PID:进程标识符即ID号
        USER:进程所有者
        FD:文件描述符
        TYPE:文件类型,包括REG(文件)、DIR(目录)、CHR(字符设备)、BLK(块设备)、UNIX(UNIX域套接字)、FIFO(先进先出队列)、IPv4(网际协议套接字)等
        DEVICE:磁盘名称
        SIZE/OFF:文件大小
        NODE:索引节点(文件在磁盘上的标识)
        NAME:文件名称
        其中,FD列比较有意思,用于指定文件描述,有很多种值,具体如下:
        cwd:表示应用程序的当期工作目录即程序启动目录,除非它本身对这个目录进行修改。
        txt:表示是程序代码,比如应用程序二进制文件本身或共享库。
        数值:表示应用程序的文件描述符,比如10u,10是文件描述符,u表示文件被打开并处于读取/写入模式,而不是只读r或者只写w模式,大写W表示该应用程序具有对整个文件的写锁,用于确保每次只能打开一个应用程序实例。
        lsof常见用法是统计应用程序打开的文件名称和数目、查找应用程序将日志记录到何处、定位应用程序是否耗尽文件描述符等,其语法格式如下:
        #lsof [options] filename
        lsof的常用参数选项如下:
        lsof filename:显示打开指定文件的所有进程
        lsof -a:表示两个参数都必须满足时才显示结果
        lsof -c string:显示COMMAND列中包含指定字符的进程所有打开的文件
        lsof -u username:显示所属user进程打开的文件
        lsof -g gid:显示归属gid的进程情况
        lsof +d /DIR/:显示目录下被进程打开的文件
        lsof +D /DIR/:显示目录下被进程打开的文件,但是会搜索目录下的所有目录,时间相对较长
        lsof -d FD:显示指定文件描述符的进程
        lsof -n:不将IP转换为hostname,缺省是不加上-n参数
        lsof -i:用以显示符合条件的进程,具体条件组合如下:
        lsof -i [46][protocol][@hostname|hostaddr][:service|port]
            46:IPv4或者IPv6
            protocol:TCP或者UDP
            hostname:Internet host name
            hostaddr:IPv4地址
            service:/etc/service,服务名称,可以有多个
            port:监听端口号,可以有多个          

二、使用实例
1、条件查找文件
        
        上图查找指定条件为:IPv4、TCP、IP(172.28.14.224)、Port(22221)的文件集合。
2、卸载文件系统
        在卸载文件系统时,如果文件系统中有任何打开的文件,则操作都会失败,那么通过lsof就能揪出哪些进程还在使用当前要卸载的文件系统,比如:
        
        上图说明lsof在使用/proc,赶紧干掉吧
3、恢复被删文件
        当日清除系统日志或者数据库事务日志时,不小心删除了重要文件,此时,可以通过lsof来恢复这些文件。
        当某进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,其依然存在于磁盘中。这意味,虽然进程并不知道文件已经被删除了,但它仍然可以向打开该文件时生成的文件描述符进行读取和写入。除了该进程外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。
        在/proc目录下,包含了反映内核和进程树的各种文件,/proc目录挂载的是内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此,当我们对这些文件进行读取和写入时,实际上是从内存中获取相关信息。大多数与lsof相关的信息都存在于以进程的PID命名的目录中,即/proc/1234中包含的是PID为1234的进程的信息。每个进程目录中存在着各种文件,它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘的文件的符号链接和其它系统信息。lsof使用该信息和其它关于内核内部状态的信息来产生其输出,所以lsof可以显示进程的文件描述符和相关的文件名等信息,即通过访问进程的文件描述符可以找到该文件的相关信息。
        当系统中某个文件被意外地删除了,只要此时系统中还有进程正在访问该文件,那么就可以通过lsof从/proc目录下恢复该文件的内容。
        假设由于误操作将/var/log/messages文件删除了,那么可以用如下方法来恢复/var/log/messages文件内容:
        首先使用lsof来查看当前是否有进程打开/var/log/messages文件,具体如下:
        
        从上图中可以看出PID 11186(syslogd)打开文件的文件描述符为2,同时还可以看出/var/log/messages已经标记被删除了,因此,可以在/proc/11186/fd/2中查看相应的信息,具体文件内容信息如下:
        
        上图就是通过文件描述来查看文件内容的前10行,如果可以通过文件描述符查看相应的数据,那么就可以使用重定向将其复制到文件中,具体如下:
        
        插曲:对于许多应用程序,尤其是日志文件和数据库,这种恢复删除文件的方法非常有用。某次生产环境中,运维的同学为了图省事,写了一个脚本定时将xxx服务的xxx日志清除,而xxx服务用的是log4cpp,用过log4cpp的同学都知道,log4cpp只在初始化的时候打开文件,在销毁的时候关闭文件,悲剧来了,xxx服务有个bug需要通过日志来实时跟踪,这时候请求大神lsof来拯救你吧,baby
        


阅读(1392) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~