lsof 命令用于列出 Linux 等操作系统中打开的文件。名称 lsof 本身就是从这个功能派生出来的。
在本指南中,我们将通过 18 个不同的实际示例学习 lsof 命令。
在哪里使用 lsof ?
Lsof 命令主要用于检索各个进程打开的文件信息。系统中打开的文件可以是磁盘文件、网络套接字、命名管道和设备。lsof 命令的这一独特特性,使人们能够更好地调试和理解 Linux 操作系统。
如何安装 lsof ?
当我们最小安装 RHEL / CentOS / AlmaLinux / Ubuntu / OpenSUSE 的时,lsof 不是默认安装的一部分,因此使用以下命令来安装 lsof 命令。
RHEL / CentOS / AlmaLinux / Fedora 系统下安装
$ sudo yum install lsof -y
or
$ sudo dnf install lsof -y
Debian 系列 (Ubuntu / Linux Mint) 系统下安装
$ sudo apt install lsof -y
OpenSUSE 系统下安装
$ sudo zypper install lsof
1) 列出所有打开的文件
不带任何选项地运行 lsof 命令将列出系统中所有活动进程打开的文件。
注意: 由于 lsof 输出给了 STDOUT 很多信息,最好使用管道 | 操作来逐页查看这个输出。
# lsof | more
如果仔细检查,上面的命令输出提供了许多参数的信息。例如,进程 systemd 的进程号 (PID) 为 1,用户为 root,文件描述符 (FD) 为 cwd 等等。
FD 有很多值,因为在 Linux 系统中,文件描述符是为任何打开的文件自动生成的。下面是用于 lsof 命令的一些众所周知的 FD 值
注意: 在某些情况下,mem 后面跟着数字和各种字符,如 r, u, w 等。这些字符是 r 表示读,w 表示写,u 表示读和写。
回显中的 TYPE 为文件类型,以下是 Linux 系统中标准的文件类型。
与此一起显示的其他字段如下所示
- DEVICE –> Device id
- SIZE/OFF –> Actual size of this process (taken during run time)
- NODE –> Typically inode number of the directory or parent directory
- NAME –> Path or link
2) 列出特定文件系统打开的文件
如您所知,/proc 只在 Linux 操作系统的生命周期内存在,这个目录包含了许多重要的进程相关信息。在 /proc 上执行 lsof 将抛出有趣的输出
# lsof /proc
如前所述,此处捕获 lsof 本身的 lsof,并显示所有细节。除了 lsof,还有其他进程,如 systemd 和 rsyslogd,它们是用于交换、挂载等目的的守护进程。
同样的, 我们可以列出另一个文件系统的打开的文件
# lsof /var/log/
某些情况下,使用 df 和 du 命令相同文件系统却显示不同磁盘使用情况,使用 losf 变得非常方便,使用 lsof 命令我们可以找到在某些进程打开和使用时被删除的文件。
# lsof /var/log | grep -i "deleted"
上面的命令会给你被删除的文件的 pid,但它们仍然存在于系统中,处于删除状态。因此,为了释放文件系统的空间,我们可以通过 pid 来安全地杀死这些进程。
3) 显示 lsof 命令打开的文件列表
lsof 本身抛出一个错误消息
# lsof lsof
lsof: status error on lsof: No such file or directory
lsof 4.87
4) 列出用户打开的文件
lsof 可用于所有已登录 Linux 系统的用户。在这种情况下,lsof 将显示相应用户打开的所有文件。
列出 root 用户打开的所有文件
# lsof -u root | more
非 root 用户打开的文件列表,让我们查看 linuxtechi 用户打开的所有文件
# lsof -u linuxtechi | more
Or
# lsof -l -u linuxtechi | more
要列出除 root 外的所有打开的文件
# lsof -u ^root | more
5) 列出所有开放的 Internet 和 UNIX 域文件
使用 -i -U 选项列出系统上所有打开的 internet 和 UNIX 域文件,示例如下
# lsof -i -U
6) 列出所有打开的 IPv4 网络文件
使用-i -4 选项列出 IPv4 所有打开的网络文件
# lsof -i 4
列出特定进程所有打开的 IPv4 网络文件
语法如下 :
lsof -i 4 -a -p {process_pid}
# lsof -i 4 -a -p 1633
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rpcbind 1633 rpc 4u IPv4 16576 0t0 TCP *:sunrpc (LISTEN)
rpcbind 1633 rpc 5u IPv4 16577 0t0 UDP *:sunrpc
rpcbind 1633 rpc 10u IPv4 16649 0t0 UDP *:960
#
7) 列出所有 IPv6 打开的网络文件
假设支持 ipv6 域,则可以使用 -i 6 选项列出打开的网络文件。
# lsof -i 6
8) 列出在特定端口上运行的所有 TCP 和 UDP 进程
语法如下:
lsof -i TCP/UDP:port
假设我们想要列出 80 端口上运行的所有 TCP 进程,使用下面的命令
# lsof -i TCP:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 2594 root 4u IPv6 22703 0t0 TCP *:http (LISTEN)
httpd 2595 apache 4u IPv6 22703 0t0 TCP *:http (LISTEN)
httpd 2596 apache 4u IPv6 22703 0t0 TCP *:http (LISTEN)
httpd 2597 apache 4u IPv6 22703 0t0 TCP *:http (LISTEN)
httpd 2598 apache 4u IPv6 22703 0t0 TCP *:http (LISTEN)
httpd 2599 apache 4u IPv6 22703 0t0 TCP *:http (LISTEN)
[root@linuxtechi ~]#
列出 TCP 端口范围(1 到 1048)上所有打开的文件
# lsof -i TCP:1-1048
列出在特定端口上运行的所有 UDP 进程
# lsof -i UDP:16498
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
dhclient 2494 root 21u IPv6 20952 0t0 UDP *:16498
#
注意: 要列出 linux 系统上所有打开的 UDP 进程,请使用 lsof -i UDP 命令
9) 查看指定设备的所有打开文件
语法如下:
lsof <device-name>
查看设备 /dev/sda2 打开的文件
# lsof /dev/sda2
10) 查看 NFS 文件系统中已打开文件的进程
在某些情况下,您已经在 linux 机器上挂载了 nfs 文件系统,但是 nfs 服务器无法访问,并且希望列出该 nfs 文件系统上打开的所有进程
# lsof -b <nfs-share-mount-point>
11) 显示终端相关的打开文件
下面的命令用于终端上所有打开的文件
lsof /dev/tty {number}
# lsof /dev/tty1
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 2442 root 0u CHR 4,1 0t0 4689 /dev/tty1
bash 2442 root 1u CHR 4,1 0t0 4689 /dev/tty1
bash 2442 root 2u CHR 4,1 0t0 4689 /dev/tty1
bash 2442 root 255u CHR 4,1 0t0 4689 /dev/tty1
#
12) 列出与应用程序关联的打开文件
假设我们想要列出所有与 httpd 相关的打开文件
# lsof -c httpd
13) 列出所有网络连接
使用 -i 选项列出所有与网络相关的进程,示例如下
# lsof -i
14) 查看 IPv4 / IPv6 套接字文件
查看 IPv4 套接字文件
# lsof -i@192.168.1.189
通过带有一系列零的相关数字冒号形式的地址查找 IP 版本 6 的套接字文件,例如,循环地址(127.0.0.1)
# lsof -i@[::1]
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
master 2433 root 14u IPv6 21027 0t0 TCP localhost:smtp (LISTEN)
#
15) 列出属于某个进程 ID 的所有进程
假设我们想要列出属于特定进程 id 的所有进程,示例如下
# lsof -p 1598
16) 终止用户的所有进程
杀死所有属于 linuxtechi 用户的进程
# kill -9 `lsof -t -u linuxtechi`
17) 查看特定目录下所有打开的文件
语法如下:
lsof +D <directory-path>
列出 /var/log 目录下打开的所有文件
# lsof +D /var/log/
注意: 在上面的命令中,如果我们使用 +D 选项,那么 lsof 将递归地列出目录中所有打开的文件,如果你不想递归地列出目录中打开的文件,那么使用 +d 选项
18) 检查谁打开日志文件(找到 PID)
下面的命令用于查找是谁打开了/var/log/httpd/access.log 文件,以及该进程的 PID 是什么。然后用“ps -ef”命令我们可以找到确切的用户
# lsof -t /var/log/httpd/access_log
3109
3110
3111
3112
3113
3114
#
# ps -ef | grep -E "3109|3110|3111|3112|3113|3114" | grep -v grep
or
# ps -fp "$(lsof -t /var/log/httpd/access_log | xargs echo)"
root 3109 1 0 03:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 3110 3109 0 03:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 3111 3109 0 03:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 3112 3109 0 03:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 3113 3109 0 03:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 3114 3109 0 03:36 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
#