本节索引


  • lsof工具简介

  • lsof安装方法

  • lsof高频用法


lsof工具简介


lsof是英文单词是”list open files”的缩写,见名知义,即是一个列出当前系统打开文件的工具。如果说 netcat 是进行网络诊断的最好工具,那么lsof 就是 Unix 调试的最好工具。

lsof 遵从 Unix 哲学的典范,它只做一件事情,并且做的相当完美。它打开的文件可能是普通的文件,目录,NFS 文件,块文件,字符文件,共享库,常规管道,符号链接,Socket 流,网络 Socket,UNIX 域Socket,以及其它更多。lsof的输出除了生成单个输出列表外,lsof还能以重复模式运行,在重复模式下,它将产生输出,延迟,然后重复输出操作,直到中断或退出信号停止。

在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。

     文件描述目可使用stat命令来查看,如下 

lsof的数十种高频用法_第1张图片


lsof安装方法


许多 Unix 系统和Linux系统都内置了 lsof,提供lsof服务的包名就叫做lsof。如果你的系统没有安装,你可以从下面地址直接下载源代码。https://people.freebsd.org/~abe/

BSD 系统有一个类似的工具也可以做同样的事情,叫做 fstat。本文主要以Unix或Linux为例:

[root@vin ~]# yum install lsof -y         # 由于我之前已经安装过了
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Package lsof-4.87-4.el7.x86_64 already installed and latest version
Nothing to do


lsof高频用法


    如何使用 lsof?本文章中我会尽力列举我能想到的所有 lsof的用法,让我们先从最简单的开始,在逐渐过度到复杂用法。

### 查询帮助
    # man lsof
    # lsof -h 
     每认识一个服务或命令或工具,都要先查帮助。
  
    
### 列出所有打开的文件;不带任何参数运行 lsof 会列出所有进程打开的所有文件。
    # lsof
    COMMAND    PID  TID    USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
    systemd      1         root  cwd       DIR                8,2       258         64 /
    systemd      1         root  rtd       DIR                8,2       258         64 /
    ...

    
### 找出谁在使用某个文件
    # lsof /path/to/file     只需要执行文件的路径,lsof 就会列出所有使用这个文件的进程.
    # lsof /path/to/file1 /path/to/file2    指定多个文件,lsof 会列出所有使用这些文件的进程

    
### 递归查找某个目录中所有打开的文件
    # lsof +D /usr/lib
    # lsof | grep '/usr/lib'
    加上 +D 参数,lsof 会对指定目录进行递归查找,注意这个参数要比 grep 版本慢 。
    之所以慢是因为 +D 首先查找所有的文件,然后一次性输出。
 
    
### 列出某个用户打开的所有文件
    # lsof -u python
    # lsof -u tom,root
    # lsof -u tom -u root
    -u 选项限定只列出所有被用户 python 打开的文件,你可以通过逗号指定多个用户 。
    你也可以像第三条命令那样使用多个 -u 做同样的事情。
  
    
### 查找某个程序打开的所有文件
    # lsof -c apache
    # lsof -c apa
    # lsof -c apache -c python
    -c 选项限定只列出以某进程开头的进程打开的文件;所以你可以不用像这样写 "lsof | grep jerry"而使用"lsof -c jerry"
    你可以只制定进程名称的开头,上面第二条
    同样可以制定多个 -c 参数,例如上面第三条

    
### 列出所有由某个用户或某个进程打开的文件
    # lsof -u vinsent -c apache
    你也可以组合使用多个选项,这些选项默认进行或关联,也就是说上面的命令会输入由 vinsent 用户或是 apache 进程打开的文件。
  
    
### 列出所有由一个用户与某个进程打开的文件
    # lsof -a -u vinsent -c bash
    -a 参数可以将多个选项的组合条件由或变为与,上面的命令会显示所有由 vinsent 用户以及 bash 进程打开的文件。
    
### 列出除 root 用户外的所有用户打开的文件
    # lsof -u ^root
    root 前面的 ^ 符号,它执行取反操作,因此lsof 会列出所有 root 用户之外的用户打开的文件。

    
### 列出所有由某个 PID 对应的进程打开的文件
    # lsof -p 1
    # lsof -p 450,980,333
    -p 选项让你可以使用进程 id 来过滤输出。记住你也可以用逗号来分离多个 pid。

    
### 列出所有进程打开的文件除了某个 pid 的
    # lsof -p ^1
    同前面的用户一样,你也可以对 -p 选项使用 ^ 来进行取反。

    
### 列出所有网络连接
    # lsof -i
    lsof 的 -i 选项可以列出所有打开了网络套接字(TCP 和 UDP)的进程。

    
### 列出所有 TCP 网络连接
    # lsof -i tcp
        也可以为 -i 选项加上参数,比如 tcp,tcp 选项会强制 lsof 只列出打开 TCP sockets 的进程。


### 列出所有 UDP 网络连接
    # lsof -i udp
    同样 udp 让 lsof 只列出使用 UDP socket 的进程。

    
### 找到使用某个端口的进程
    # lsof -i :25
    # lsof -i :smtp
    :25 和 -i 选项组合可以让 lsof 列出占用 TCP 或UDP 的 25 端口的进程。
    你也可以使用 /etc/services 中制定的端口名称来代替端口号,比如上面第二条。

    
### 找到使用某个 udp 端口号或者某个 tcp 端口的进程
    # lsof -i udp:53
    # lsof -i tcp:80

    
### 找到某个用户的所有网络连接
    # lsof -a -u hacker -i
    使用 -a 将 -u 和 -i 选项组合可以让 lsof 列出某个用户的所有网络行为。
    
    
### 列出所有 NFS(网络文件系统)文件
    # lsof -N
    这个参数很好记,-N 就对应 NFS。

    
### 列出所有 UNIX 域 Socket 文件
    # lsof -U
    这个选项也很好记,-U 就对应 UNIX。
    
    
### 列出所有对应某个组 id 的进程
    # lsof -g 1234
    进程组用来逻辑上对进程进行分组,这个例子查找所有 PGID 为 1234 的进程打开的文件。

    
### 列出所有与某个描述符关联的文件
    # lsof -d 2
    # lsof -d 0-2
    这个命令会列出所有以描述符 2 打开的文件;你也可以为描述符指定一个范围。
    上述第二条命令会列出所有描述符为 0,1,2 的文件。

    
### 查看所有内存映射文件
    # lsof -d mem
 
    
### 所有加载在内存中并正在执行的进程
    # lsof -d txt

    
### 输出使用某些资源的进程 pid
    # lsof -t -i
    -t 选项输出进程的 PID,你可以将它和 -i 选项组合输出使用某个端口的进程的 PID,

    
### kill所有使用网络的进程
    # kill -9 `lsof -t -i`

    
### 循环列出文件
    # lsof -r 1
    -r 选项让 lsof 可以循环列出文件直到被中断,参数 1 的意思是每秒钟重复打印一次,
    这个选项最好同某个范围比较小的查询组合使用。例如下面的例子。
  
    
### 监测网络活动
    # lsof -r 1 -u tom -i -a