引言

《Linux fuser工具介绍》一文中,与大家一起学习了fuser工具的使用方法。"lsof"——list open files,lsof也是Linux下用于查看打开的文件以及相关联进程信息的工具,相比fuser提供更强大的功能,下面我们就来学习lsof的使用方法。

lsof输出说明

直接执行lsof,将输出系统中所有打开文件的信息,这里说的“文件”不单指一般的文件,还包括目录、socket套接字、设备文件和命名管道:

#lsof
COMMAND     PID       USER   FD      TYPE             DEVICE SIZE/OFF       NODE NAME
init                 root  cwd       DIR                ,                /
init                 root  rtd       DIR                ,                /
init                 root  txt       REG                ,         /sbin/init
init                 root  mem       REG                ,         /lib64/libdl-.so
init                 root   ,      0t0        /dev/initctl
……

每行显示一个打开的文件,各列含义如下:

  • COMMAND:与文件关联进程的名称
  • PID:进程PID
  • USER:拉起进程的用户
  • FD:指示进程与文件的关联关系
  • TYPE:指示文件类型
  • DEVICE:指示文件所在设备的设备号(major,minor)
  • SIZE/OFF:指示文件的大小或进程对文件操作的偏移量
  • NODE:文件索引标识
  • NAME:文件名

FD列值的含义与fuser查询结果中PID后接字符的含义相同,指示了进程与文件的关联关系,有以下常见取值:

  • cwd:进程工作目录
  • txt:进程由该文件拉起(如二进制文件或脚本)
  • rtd:进程的根目录
  • mem:内存映射文件
  • N(u/w/r):指示该文件为进程打开的第N个文件描述符,u为可读可写模式,w为可写模式,r为可读模式

TYPE列有以下常见取值:

  • REG:一般文件
  • DIR:目录
  • CHR:字符设备
  • BLK:块设备
  • FIFO:命名管道
  • PIPE:管道
  • IPV4:ipv4套接字
  • unix:unix域套接字

根据以上字段,我们就可以了解到哪个文件以何种关联方式与哪个进程关联。但单执行lsof输出太多,为获取必要输出,我们就得加一些过滤选项。

查询某个进程打开的文件

lsof常见的用法是查找进程打开的文件名称和文件数目,以下我们使用lsof查看pid为14586的syslog-ng进程使用了哪些文件:

# lsof -p
COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
syslog-ng  root  cwd    DIR                ,             /
syslog-ng  root  rtd    DIR                ,             /
syslog-ng  root  txt    REG                ,     /sbin/syslog-ng
syslog-ng  root  mem    REG                ,      /lib64/libnss_files-.so
syslog-ng  root    0r   CHR                ,      0t0     /dev/null
syslog-ng  root    1w   CHR                ,      0t0     /dev/null
syslog-ng  root    2w   CHR                ,      0t0     /dev/null
syslog-ng  root     /var/lib/dhcp/dev/log
syslog-ng  root     /dev/log
syslog-ng  root    5w   REG                ,    /var/log/messages

从以上查询结果可知,syslog-ng进程由/sbin/syslog-ng拉起,进程根目录和当前工作目录均为系统根目录,进程的标准输出、标准输入和标准出错输出均被重定向至/dev/null,/var/log/messages被syslog-ng以可写模式打开。

Linux限制了进程能够打开文件的数目,通过如下命令可以查看该限制:

# ulimit -n

若进程打开文件句柄的数目超过系统限制,则相应进程不能正常服务,使用如下方式我们可以查看各个进程打开文件句柄的数目:

# lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr| more

查询某个文件被哪些进程打开

lsof命令后直接接文件名,可以查到该文件被哪些进程打开:

# lsof /var/log/messages
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
syslog-ng  root    5w   REG    ,    /var/log/messages

要删除文件时要先中止进程,而不是直接删除这个文件。

在umount文件系统时,如果文件系统中有打开的文件,那么umount操作会失败,报“device is busy”。这时可使用”lsof /dev/sdaX”显示sdaX文件系统中被打开的所有文件,再关闭所列文件。

进程的当前工作目录影响文件系统的卸载,这也是为什么在编写后台进程时需要将其工作目录设置为根目录的原因,

恢复删除文件

最后,来介绍使用lsof命令恢复被删文件的用法:某文件被删除,但从lsof能查到该文件仍被某进程打开,这时我们可以恢复被删文件。以下通过一个小程序说明该用法:

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
        int fd;
        ];
        fd = open("test.txt", O_RDONLY);
        read(fd, buf, );
        )
        {
                sleep();
                printf("%s", buf);
        }
        ;
}

以上程序打开test.txt文件并定时输出该文件内容,在编译、拉起该程序之后,我们将test.txt文件删除,之后使用lsof查到打开该文件的进程:

# lsof | grep test.txt
ttt              root    3r      REG                ,             /tmp/lx/test.txt (deleted)

接着,在/proc中可以看到该进程打开的文件描述符如下:

# ll /proc//fd
total
lrwx------  root root  May   :  -> /dev/pts/
lrwx------  root root  May   :  -> /dev/pts/
lrwx------  root root  May   :  -> /dev/pts/
lr-x------  root root  May   :  -> /tmp/lx/test.txt (deleted)

执行以下命令我们即可将/tmp/lx/test.txt文件的内容恢复至/tmp/test.txt:

# cat /proc//fd/ > /tmp/test.txt

当进程打开了某个文件时,只要该进程保持打开该文件,即使将文件删除,文件依然存在于磁盘中。进程并不知道文件已经被删除,它依然可以使用打开该文件时获取到的文件描述符进行读取和写入。除了该进程外,这个文件是不可见的,因为已经删除了其相应的目录条目。

小结

本文介绍了lsof的使用方法,包括lsof命令的输出格式,如何根据某进程查询其打开的文件,又如何查询某文件被哪些进程打开,以及判断进程打开文件数是否达到上限的方法、删除文件/卸载文件系统时需注意的事项,最后介绍了使用lsof恢复被删除文件的方法。

Linux lsof工具介绍的更多相关文章

  1. Linux性能工具介绍

    l  Linux性能工具介绍 p  CPU高 p  磁盘I/O p  网络 p  内存 p  应用程序跟踪 l  操作系统与应用程序的关系比喻为“唇亡齿寒”一点不为过 l  应用程序的性能问题/功能问 ...

  2. 常用linux小工具介绍

    1.ctags(Generate tag files for source code)是vim下方便代码阅读的工具.尽管ctags也可以支持其它编辑器,但是它正式支持的只有VIM. ctags 最先是 ...

  3. Linux bpytop工具介绍

    一.工具简介: Easy to use, with a game inspired menu system. Full mouse support, all buttons with a highli ...

  4. 用户管理 之 Linux 用户管理工具介绍

    Linux是一个多用户的操作系统,她有完美的用户管理工具,这些工具包括用户的查询.添加.修改,以及用户之间相互切换的工具等:通过这些工具,我们能安全.轻松的完成用户管理: 在这里我们要引入用户控制工具 ...

  5. Rsync,Linux日志及Screen工具介绍

    第十六次课 Rsync,Linux日志及Screen工具介绍 目录 一.rsync工具介绍 二.rsync常用选项 三.rsync通过ssh同步 四. rsync通过服务同步 五.linux系统日志 ...

  6. [原创]Linux下网络性能测试Netperf工具介绍及安装

    [原创]Linux下网络性能测试Netperf工具介绍及安装 1 官方网站 http://www.netperf.org/netperf/ 2 Netperf介绍 Netperf是一种网络性能的测试工 ...

  7. Linux 文件内容查看工具介绍-cat,less,more,tail,head

    Linux 文件内容查看工具介绍 作者:北南南北来自:LinuxSir.Org摘要: 本文讲述几种常用文件内容的查看工具,比如cat.more.less.head.tail等,把这些工具最常用的参数. ...

  8. Linux操作系统的打包/归档工具介绍

    Linux操作系统的打包/归档工具介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  9. Linux操作系统的压缩、解压缩工具介绍

    Linux操作系统的压缩.解压缩工具介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.compress/uncompress命令常用参数 Linux compress命令: ...

随机推荐

  1. Flink会话窗口测试

    Flink会话窗口测试 一.测试结论: 1.会话窗口的间隔时间和水位线作用一样,表示输出现在时间 - 间隔时间之前所有未结算时间的数据,作用类似于水位线,但是和水位线开闭不一样. 2.会话窗口显示的数 ...

  2. .Net高级编程-自定义错误页 web.config中<customErrors>节点配置

    错误页 1.当页面发生错误的时候,ASP.Net会将错误信息展示出来(Sqlconnection的错误就能暴露连接字符串),这样一来不好看,二来泄露网站的内部实现信息,给网站带来安全隐患,因此需要定制 ...

  3. 自我救赎 → 利用 IDEA 和 Spring Boot 搭建 SSM

    前言 开心一刻 儿子读高中放学回来了,一向不管他学习的我突然来了兴趣,想看看他的学习他的状况,抄起他的数学习题看了起来,当看到 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x ...

  4. NOIP最后阶段每日小记

    前言:最后几天了,记录一下每天的经验.教训.启示.大牛路过请补充一点内容…… 2017-10-31 21:32 今天考试打完第一题就知道是AK场,然后就死命搞题,结果第一题手贱多打了一个%,本机无显示 ...

  5. MyBatis 接口多参数的处理方法

    From<MyBatis从入门到精通> 1.接口类中增加的方法: /* 2.7 多个接口参数的用法 多个参数时,可以选取的方案有:使用Map类型或者使用@Param注解 使用Map类型作为 ...

  6. fjnuoj 1003 学长的QQ号

    题目: //QQ是一个9位数,由1,2,3,4,5,9组成,且第1.6位数字相同,第2.4位数字相同,第5.7位数字相同.            //我的QQ就在符合上诉条件中的所有9位数从小到大排第 ...

  7. python函数对象-命名空间-作用域-02

    函数对象 函数是第一对象: # 函数名指向的值可以被当做参数传递 函数对象的特性(*****灵活运用,后面讲装饰器会用到) 函数名可以像变量一样被传递 # 变量可以被传递 name = 'jason' ...

  8. Java EE.JSP.指令

    JSP的指令是从JSP向Web容器发送消息,它用来设置页面的全局属性,如输出内容类型等. JSP的指令的格式为:<%@ 指令名 属性="属性值"%> 1.page指令 ...

  9. 基础篇-1.2Java世界的规章制度(下)

    1 Java运算符 Java世界中的运算其实就是数学运算,而运算符就是其中的媒介. 算术运算符 操作符 描述 + 加法,对符号两边的数值相加 - 减法,符号左边的数减去右边的数 * 乘法,符号两边的数 ...

  10. java用最少循环求两个数组的交集、差集、并集

    import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List ...