一、命令简介
lsof(list open files)是 Linux 系统中功能强大的工具,用于列出当前系统打开的文件信息。在 Linux 中,”一切皆文件”,因此 lsof 可以显示进程打开的文件、目录、网络连接、设备等几乎所有资源,是系统管理员进行故障排查、性能分析和安全审计的必备工具。
二、基本语法
lsof [选项] [文件名]
权限要求:普通用户只能查看自己拥有的进程信息,root 用户可以查看所有进程。 默认行为:如果不指定选项和文件名,显示所有打开的文件信息。
三、常用选项详解
3.1 基本选项
| 选项 | 功能说明 | 示例 |
|---|
-c <进程名> | 显示指定进程名打开的文件 | lsof -c sshd |
-p <PID> | 显示指定进程ID打开的文件 | lsof -p 1234 |
-u <用户名> | 显示指定用户打开的文件 | lsof -u root |
-i | 显示网络连接信息 | lsof -i |
-i :<端口> | 显示指定端口的连接 | lsof -i :80 |
-i tcp | 显示TCP连接 | lsof -i tcp |
-i udp | 显示UDP连接 | lsof -i udp |
-d <文件描述符> | 显示指定文件描述符 | lsof -d 0-2 |
-t | 只显示进程ID | lsof -t |
-s | 显示文件大小 | lsof -s |
-n | 不解析主机名 | lsof -n |
-P | 不解析端口名 | lsof -P |
-r <秒数> | 持续监控,按指定间隔刷新 | lsof -r 5 |
-F | 以机器可读格式输出 | lsof -F |
-V | 显示版本信息 | lsof -V |
-h | 显示帮助信息 | lsof -h |
3.2 组合选项
| 选项组合 | 功能说明 | 示例 |
|---|
-i :<端口> | 显示指定端口的连接 | lsof -i :22 |
-i @<主机> | 显示指定主机的连接 | lsof -i @192.168.1.1 |
-i tcp:<端口> | 显示指定TCP端口的连接 | lsof -i tcp:80 |
-i udp:<端口> | 显示指定UDP端口的连接 | lsof -i udp:53 |
四、输出字段解释
lsof 的输出包含以下关键字段:
| 字段 | 说明 |
|---|
| COMMAND | 进程名称 |
| PID | 进程ID |
| USER | 进程所有者 |
| FD | 文件描述符(cwd=当前目录,txt=程序文本,mem=内存映射文件) |
| TYPE | 文件类型(REG=普通文件,DIR=目录,CHR=字符设备,FIFO=管道,IPv4=IPv4套接字) |
| DEVICE | 设备号 |
| SIZE/OFF | 文件大小/偏移量 |
| NODE | 索引节点号 |
| NAME | 文件名或连接信息 |
五、实际应用场景
5.1 查看所有打开的文件
# 显示所有打开的文件(信息量大,建议配合grep使用)
lsof
# 显示前10行
lsof | head -10
5.2 查看指定进程打开的文件
# 查看sshd进程打开的文件
lsof -c sshd
# 查看指定PID的进程打开的文件
lsof -p 1234
# 查看nginx进程打开的文件
lsof -c nginx
5.3 查看网络连接
# 查看所有网络连接
lsof -i
# 查看TCP连接
lsof -i tcp
# 查看UDP连接
lsof -i udp
# 查看指定端口的连接
lsof -i :80
lsof -i :22
# 查看指定IP的连接
lsof -i @192.168.1.100
# 查看指定端口的TCP连接
lsof -i tcp:80
# 查看指定端口的UDP连接
lsof -i udp:53
5.4 查看指定用户打开的文件
# 查看root用户打开的文件
lsof -u root
# 查看指定用户打开的网络连接
lsof -u root -i
# 查看除root外的其他用户打开的文件
lsof -u ^root
5.5 查看文件被哪些进程占用
# 查看指定文件被哪些进程打开
lsof /var/log/syslog
# 查看指定目录被哪些进程打开
lsof /var/log/
# 查看指定设备文件
lsof /dev/sda1
5.6 查看文件描述符
# 查看标准输入输出错误(0,1,2)
lsof -d 0-2
# 查看所有文件描述符
lsof -d 0-1024
5.7 持续监控
# 每5秒刷新一次,持续监控
lsof -r 5
# 监控指定进程的网络连接
lsof -c nginx -i -r 3
六、常见问题排查
6.1 无法卸载磁盘
# 查看哪些进程占用了挂载点
lsof /mnt/data
# 终止占用进程
kill -9 $(lsof -t /mnt/data)
6.2 端口被占用
# 查看80端口被哪个进程占用
lsof -i :80
# 查看所有监听的端口
lsof -i -s TCP:LISTEN
# 查看指定进程监听的端口
lsof -c nginx -i -s TCP:LISTEN
6.3 文件被占用无法删除
# 查看哪些进程打开了指定文件
lsof /var/log/nginx/access.log
# 查看哪些进程打开了已删除的文件(空间未释放)
lsof | grep deleted
6.4 网络连接异常
# 查看所有ESTABLISHED状态的连接
lsof -i -s TCP:ESTABLISHED
# 查看TIME_WAIT状态的连接
lsof -i -s TCP:TIME_WAIT
# 查看CLOSE_WAIT状态的连接
lsof -i -s TCP:CLOSE_WAIT
七、高级用法
7.1 组合条件查询
# 查看root用户的网络连接
lsof -u root -i
# 查看指定进程的网络连接
lsof -c nginx -i
# 查看指定用户和端口的连接
lsof -u root -i :22
# 查看指定进程打开的文件和网络连接
lsof -c mysql -i -d 0-1024
7.2 统计信息
# 统计打开文件数量最多的进程
lsof | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
# 统计网络连接数最多的进程
lsof -i | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
7.3 脚本中使用
#!/bin/bash
# 检查端口是否被占用
PORT=8080
if lsof -i :$PORT > /dev/null 2>&1; then
echo "端口 $PORT 已被占用"
PID=$(lsof -t -i :$PORT)
echo "占用进程PID: $PID"
echo "进程信息:"
ps -p $PID -o pid,user,comm
else
echo "端口 $PORT 可用"
fi
八、注意事项
8.1 权限限制
# 普通用户只能查看自己拥有的进程
lsof -u root
# 可能需要 sudo 权限
sudo lsof -u root
8.2 性能影响
# lsof 会扫描 /proc 目录,在进程较多的系统上可能较慢
# 建议使用具体条件缩小查询范围
lsof -c nginx # 而不是 lsof | grep nginx
8.3 输出格式
# 使用 -F 选项生成机器可读格式
lsof -F
# 使用 -t 选项只显示PID,适合脚本处理
lsof -t -i :80
九、与相关命令对比
9.1 lsof vs netstat
| 特性 | lsof | netstat |
|---|
| 功能范围 | 所有打开的文件(包括网络) | 主要网络连接 |
| 进程信息 | 显示进程名和PID | 需要配合 ps |
| 权限要求 | 需要查看 /proc | 普通用户可用 |
| 输出格式 | 详细,可定制 | 固定格式 |
9.2 lsof vs fuser
| 特性 | lsof | fuser |
|---|
| 功能范围 | 所有打开的文件 | 指定文件或目录 |
| 输出信息 | 详细进程信息 | 进程PID |
| 终止进程 | 需要配合 kill | 支持直接终止 |
十、总结
lsof命令是 Linux 系统管理中的瑞士军刀,通过灵活的选项组合,可以快速定位和解决各种系统问题。无论是网络连接异常、文件占用、端口冲突还是资源泄露,lsof 都能提供详细的诊断信息。掌握 lsof 的使用方法,能够显著提升系统故障排查和性能分析的效率。