1、lsof命令简介

lsof是list open files的简称,它的作用主要是列出系统中打开的文件,基本上linux系统中所有的对象都可以看作文件,lsof可以查看用户和进程操作了哪些文件,也可以查看系统中网络的使用情况,以及设备的信息。

在终端下输入lsof命令即可显示系统打开的文件,它访问核心内存和各种文件,需要root用户身份才能发挥其功能。

# lsof
COMMAND    PID  TID    USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
systemd      1         root  cwd       DIR                8,2      4096          2 /
systemd      1         root  rtd       DIR                8,2      4096          2 /
systemd      1         root  txt       REG                8,2   1612152    2893576 /usr/lib/systemd/systemd
systemd      1         root  mem       REG                8,2     20112    2888194 /usr/lib64/libuuid.so.1.3.0
systemd      1         root  mem       REG                8,2    261456    2888419 /usr/lib64/libblkid.so.1.1.0
systemd      1         root  mem       REG                8,2     90664    2887685 /usr/lib64/libz.so.1.2.7
systemd      1         root  mem       REG                8,2    157424    2888172 /usr/lib64/liblzma.so.5.2.2
......

直接运行lsof,会列出系统中所有打开的文件,每个文件一行,其中每列信息的含有如下:

COMMAND:进程名称

PID:进程ID

USER:进程运行的用户名

FD:表示文件描述符,如:cwd当前工作目录,mem内存映射文件,mmap内存映射设备,txt应用文本(代码和数据),其次数值表示应用程序的文件描述符,这是打开文件时返回的一个整数,u表示该文件处于读取和写入模式,®为只读,(w)为只写模式,大写W为对整个文件的写锁权限,初始打开一个应用程序时有具有三个文件描述符,从0到2分别表示标准输入,输出和错误输出,所以大多数应用程序打开的文件的PD都是从3开始的

TYPE:表示文件的类型,如,REG普通文件,DIR目录,CHR字符文件,BLK设备文件,UNIX为Unix套接字,FIFO先进先出队列,IPv4网际协议IP套接字

DEVICE:文件所在的设备

SIZE:文件的大小

NODE:索引节点,文件在磁盘的标识符

NAME:打开文件的名称

2、lsof查看文件和进程

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 or IPv6

            protocol --> TCP or UDP

            hostname --> Internet host name

            hostaddr --> IPv4地址

            service --> /etc/service中的 service name (可以不只一个)

            port --> 端口号 (可以不只一个)


1)列出某个进程打开的所有文件

lsof -p 1149

2)列出某个用户打开的文件

lsof -u root

3)列出所有不是某个用户打开的文件,也就是取反,在用户名前添加^符号

lsof -u ^root

4)列出某个文件被哪些进程打开使用

lsof /dev/null

5)列出访问某个目录的所有进程

lsof +d /dev/

6)递归列出访问某个目录下所有进程

lsof +D /var/

7)列出某个进程名使用的文件信息

lsof -c dhcpd

3、lsof查看网络信息

lsof也可以查看网络信息,如查看某个端口的使用情况

1)列出所有的网络链接信息

lsof -i

2)只列出某个协议类型的网络链接信息

lsof -i TCP

3)查看某个端口的网络链接状态

lsof -i :67

4)查看链接到某个主机的网络状态

lsof -i @192.168.146.1

5)查看连接到某个主机的特定端口的网络状态

lsof -i @192.168.146.1:80

6)列出当前主机监听的端口

lsof -i -s TCP:LISTEN

-s P:S参数跟着两个字段,协议和状态,中间用冒号隔开,如上表示TCP协议的监听状态,也可以查看处于连接的TCP网络状态:

lsof -i -s TCP:ESTABLISHED

实用的命令:

lsof `which httpd`    #列出那个进程使用了apache的执行文件
lsof /dev/cdrom      #列出那个进程在使用光驱
lsof -u 1000         #查看UID为1000的用户使用的进程
lsof -i TCP@[url]  #查看哪个进程打开了TCP链接到主机的80端口 
lsof -i tcp@ -r  #不断查看目前tfp链接的情况

4、通过lsof恢复删除的文件

通过lsof恢复已删除的文件,前提条件的是这个文件有程序正在使用,可以通过lsof /path/to/filename能查看到正在使用此文件的程序,下面我们以日志文件message为例实验下:

1)查看使用文件的实用程序

lsof /var/log/messages
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
abrt-watc  671 root    4r   REG    8,2   516027 1311595 /var/log/messages
rsyslogd  1148 root    6w   REG    8,2   516027 1311595 /var/log/messages

2)删除message文件

rm -rf /var/log/messages

3)通过上面查看的进程ID我们在/proc目录下找到该进程的文件目录,然后通过FD,找到FD目录的文件编号,然后对文件进行恢复

如:上面PID为1148那我们先找到/proc目录下进程为1148的目录,然后cd到FD目录下,上面FD显示文件使用6w打开,表示在6文件中以锁的方式打开

cd /proc/1148/fd

查看下6文件中的文件内容,是不是和之前删除的文件一样呢:

tail -n 10 6

下面开始通过命令恢复:

cat /proc//1148/fd/6 >/var/log/messages