lsof 命令详解
lsof(List Open Files)是 Linux/Unix 系统中一个强大的实用工具,用于列出当前系统上所有打开的文件。在 Linux 哲学中,“一切皆文件”,因此 lsof 不仅可以查看普通文件的打开情况,还可以查看目录、设备、库、网络套接字(TCP/UDP)、管道等资源的占用。它对于系统管理员排查问题(如文件无法卸载、端口被占用、进程异常等)非常有用。
基本语法
lsof [options] [names]
其中 names 可以是文件名、目录名、进程名、PID、用户等,用于过滤输出。
输出字段解释
默认情况下,lsof 输出包含以下列(可通过 -F 选项自定义格式):
| 列名 | 说明 |
|---|---|
| COMMAND | 打开文件的进程名称(仅前几个字符) |
| PID | 进程 ID |
| TID | 线程 ID(如果有,否则为空) |
| USER | 进程所有者的用户名或 UID |
| FD | 文件描述符(如 cwd、txt、mem、数字等) |
| TYPE | 文件类型(如 REG、DIR、CHR、IPv4、IPv6 等) |
| DEVICE | 设备号(主设备号:次设备号) |
| SIZE/OFF | 文件大小或偏移量(字节) |
| NODE | 文件的 inode 号(或协议信息) |
| NAME | 文件挂载点、文件名或连接信息 |
FD 字段常见值:
cwd:当前工作目录txt:程序文本(代码段)mem:内存映射文件数字:文件描述符编号(如 0u、1w、2u),u 表示读写,r 表示只读,w 表示只写
TYPE 字段常见值:
REG:普通文件DIR:目录CHR:字符设备BLK:块设备FIFO:管道IPv4/IPv6:IPv4/IPv6 套接字unix:Unix 域套接字
常用选项详解
1. 列出所有打开的文件(默认)
lsof
输出通常非常庞大,需要结合过滤使用。
2. 按进程筛选
- 指定进程名称:
lsof -c sshd(显示 sshd 进程打开的文件,支持通配符-c ssh匹配 sshd、ssh-agent 等) - 指定 PID:
lsof -p 1234(显示 PID 为 1234 的进程打开的文件,可用逗号分隔多个 PID) - 排除 PID:
lsof -p ^1234(排除 PID 1234)
3. 按用户筛选
- 指定用户名:
lsof -u alice(显示用户 alice 的进程打开的文件) - 排除用户:
lsof -u ^root(排除 root 用户)
4. 按文件或目录筛选
- 查看特定文件被哪些进程打开:
lsof /var/log/syslog - 查看目录下所有打开的文件:
lsof +d /var/log/(仅目录本身及其直接子文件,不递归) - 递归查看目录树:
lsof +D /var/log/(递归,较慢,谨慎使用)
5. 网络相关(非常常用)
- 显示所有网络连接:
lsof -i - 显示 TCP/UDP 连接:
lsof -i tcp或lsof -i udp - 显示特定端口:
lsof -i :80(查看 80 端口被谁占用) - 显示特定协议和端口范围:
lsof -i tcp:1-1024 - 显示处于 LISTEN 状态的端口:
lsof -i tcp -s tcp:LISTEN(Linux 支持 -s 选项过滤状态) - 显示与特定主机的连接:
lsof -i @192.168.1.1(发往或来自该 IP) - 更精细过滤:
lsof -i @192.168.1.1:22(指定主机和端口)
6. 其他常用选项
- 列出某个文件描述符对应的信息:
lsof -d 1(显示所有进程的 fd=1 的文件) - 列出所有打开但已删除的文件:
lsof +L1(显示 link count < 1 的文件,即已删除但仍在使用的文件,常用于排查磁盘空间未释放) - 以 PID 格式输出:
lsof -t -i :80(仅输出占用 80 端口的进程 PID,适合脚本使用) - 重复模式:
lsof -r 2(每 2 秒重复输出,类似 top,可用于监控) - 查看某个命令的打开文件:
lsof -c bash
典型使用场景及示例
场景1:查找占用端口的进程
# 查看 80 端口被哪个进程占用
sudo lsof -i :80
输出示例:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 1234 root 6u IPv4 54321 0t0 TCP *:80 (LISTEN)
nginx 1235 nobody 6u IPv4 54321 0t0 TCP *:80 (LISTEN)
场景2:查看某个进程打开的所有文件
lsof -p 1234
场景3:查看某个用户正在使用的文件
lsof -u alice
场景4:恢复误删除但仍在被进程使用的文件
如果一个文件被删除但进程仍持有句柄,磁盘空间不会立即释放。可以找出该进程并重启,或通过 /proc 恢复数据。
# 找出已删除但打开的文件
sudo lsof +L1# 例如输出显示 /var/log/syslog (deleted),记下 PID 和 FD
# 恢复方法:
cp /proc/1234/fd/4 /tmp/recovered_syslog
场景5:查看所有 TCP 监听端口及其进程
sudo lsof -i tcp -s tcp:LISTEN
场景6:查看某个程序是否运行并打开特定文件
lsof -c rsyslog | grep /var/log/syslog
场景7:列出某个挂载点下被打开的文件(用于无法卸载磁盘)
# 查看 /home 分区有哪些文件被占用
sudo lsof /home
场景8:显示每个进程打开的文件数量
lsof | awk '{print $2}' | sort | uniq -c | sort -nr
注意事项
- 权限要求:普通用户只能查看自己进程的信息,查看其他用户或系统进程需要
sudo或 root 权限。 - 性能影响:
lsof +D递归目录可能会产生大量 I/O,在大型文件系统上慎用。 - 输出解析:对于网络连接,
NAME列显示连接信息(如->192.168.1.2:https),NODE列显示协议类型。 - 与内核版本相关:部分选项(如
-s过滤状态)可能在不同系统上略有差异,建议查阅 man 手册。
