linux lsof命令

lsof命令 用于列出当前系统打开的文件(list open files)。在Linux系统中,一切皆文件,包括普通文件、目录、块设备、字符设备、网络套接字等。lsof是系统调试和性能分析的强大工具。

命令格式

lsof [选项] [文件名/目录名]

常用选项

选项 说明
-a AND逻辑,组合多个条件
-c 进程名 列出指定进程打开的文件
-p PID 列出指定PID打开的文件
-u 用户名 列出指定用户打开的文件
-d 文件描述符 列出指定文件描述符的文件
-i [条件] 列出网络连接
-n 不解析主机名(显示IP)
-P 不解析端口名(显示端口号)
-t 仅输出PID(静默模式)
+D 目录 递归列出目录下所有打开的文件
-U 列出UNIX域套接字
-r [秒] 重复执行(间隔时间)
-s 列出文件大小和偏移量
-g [PGID] 按进程组ID列出
-l 不将UID转换为用户名
-F 格式字符 指定输出格式

输出字段说明

字段 说明
COMMAND 进程名称
PID 进程ID
USER 进程所有者
FD 文件描述符
TYPE 文件类型
DEVICE 设备号
SIZE/OFF 文件大小/偏移量
NODE 索引节点号
NAME 文件名/路径

FD(文件描述符)字段说明

说明
cwd 当前工作目录
rtd 根目录
txt 程序代码
mem 内存映射文件
数字 实际文件描述符
0u 标准输入
1u 标准输出
2u 标准错误
r 只读打开
w 只写打开
u 读写打开

使用实例

1. 列出所有打开的文件(基本用法)
lsof
2. 查看指定进程打开的文件
# 查看nginx进程打开的文件
lsof -c nginx

# 查看PID为1234的进程打开的文件
lsof -p 1234

# 查看多个进程
lsof -p 1234,5678,9012
3. 查看指定用户打开的文件
# 查看root用户打开的文件
lsof -u root

# 查看多个用户
lsof -u root,www-data

# 排除特定用户(前面加^)
lsof -u ^root
4. 查看网络连接
# 查看所有网络连接
lsof -i

# 查看TCP连接
lsof -i TCP

# 查看UDP连接
lsof -i UDP

# 查看指定端口的连接
lsof -i :80
lsof -i :22
lsof -i :3306

# 查看指定IP的连接
lsof -i @192.168.1.100
lsof -i @192.168.1.100:22

# 查看指定协议的连接
lsof -i TCP:80
lsof -i UDP:53
5. 查看指定文件/目录被哪些进程打开
# 查看文件被哪些进程使用
lsof /var/log/syslog
lsof /etc/passwd

# 查看目录被哪些进程使用(不递归)
lsof /var/log/

# 递归查看目录及其子目录
lsof +D /var/log/
6. 查看文件描述符
# 查看指定文件描述符
lsof -d 0-2      # 标准输入输出错误
lsof -d mem      # 内存映射文件
lsof -d txt      # 程序代码段
7. 组合条件查询
# AND逻辑(同时满足多个条件)
lsof -a -u root -i TCP:22

# 查看root用户的nginx进程打开的网络连接
lsof -a -u root -c nginx -i

# 查看非root用户的ssh连接
lsof -a -u ^root -c ssh -i
8. 不解析主机名和端口名
# 显示IP而不是主机名
lsof -n -i

# 显示端口号而不是服务名
lsof -P -i

# 同时使用
lsof -nP -i
9. 静默模式(只输出PID)
# 只输出占用80端口的进程PID
lsof -t -i:80

# 结合kill命令使用
kill -9 $(lsof -t -i:8080)
10. 重复执行(监控)
# 每5秒刷新一次
lsof -r 5

# 每2秒刷新一次,共执行3次
lsof -r 2 -i:80
11. 查看UNIX域套接字
# 查看所有UNIX域套接字
lsof -U

# 查看特定UNIX域套接字
lsof /var/run/docker.sock
lsof /tmp/mysql.sock
12. 按进程组查看
# 查看进程组ID为1234的所有进程打开的文件
lsof -g 1234
13. 查看文件大小和偏移量
# 显示文件大小和偏移量信息
lsof -s

实际输出示例

示例1:查看网络连接
$ lsof -i:22
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1234 root    3u  IPv4  12345      0t0  TCP *:ssh (LISTEN)
sshd    5678 root    3u  IPv6  23456      0t0  TCP *:ssh (LISTEN)
ssh    9012 alice    3u  IPv4  34567      0t0  TCP 192.168.1.100:ssh->192.168.1.200:54321 (ESTABLISHED)
示例2:查看nginx进程打开的文件
$ lsof -c nginx
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
nginx   1234     root  cwd    DIR  253,0     4096       2 /
nginx   1234     root  rtd    DIR  253,0     4096       2 /
nginx   1234     root  txt    REG  253,0  1234567  123456 /usr/sbin/nginx
nginx   1234     root  mem    REG  253,0   123456  234567 /lib/x86_64-linux-gnu/libc.so.6
nginx   1235 www-data    3u  IPv4  34567      0t0     TCP *:http (LISTEN)
nginx   1236 www-data    4u  IPv4  45678      0t0     TCP 192.168.1.100:http->192.168.1.200:54321 (ESTABLISHED)
示例3:查看指定目录
$ lsof /var/log/
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
rsyslog 1234 root    4w   REG  253,0   123456  789 /var/log/syslog
nginx   5678 root    2w   REG  253,0    23456  890 /var/log/nginx/error.log
cron   9012 root    1w   REG  253,0     3456  901 /var/log/cron.log

实用场景和技巧

网络问题排查
  • 查看端口占用情况
  • 排查网络连接泄漏
  • 监控网络连接状态
  • 查找恶意连接
文件系统问题
  • 查找文件被哪个进程占用
  • 解决"Device or resource busy"错误
  • 磁盘空间异常增长分析
  • 日志文件轮转问题
系统调试
  • 进程资源泄漏分析
  • 文件描述符泄漏排查
  • 内存映射文件分析
  • 共享库依赖问题
安全审计
  • 监控可疑文件访问
  • 检测未授权网络连接
  • 审计用户文件操作
  • 检测后门程序

实用命令组合

# 查看占用端口80的进程
lsof -i :80 | grep LISTEN

# 查看进程打开的文件数量
lsof -p 1234 | wc -l

# 查看所有TCP连接,按进程分组
lsof -i TCP | awk '{print $1}' | sort | uniq -c | sort -nr

# 查找所有监听端口的进程
lsof -i -s TCP:LISTEN

# 查看指定用户的网络连接
lsof -a -u username -i

# 查找所有打开的日志文件
lsof | grep '\.log$'

# 查看MySQL打开的文件
lsof -c mysqld | grep /var/lib/mysql

故障排查示例

场景1:卸载设备时提示"Device or resource busy"
# 查看哪个进程在使用设备
lsof /dev/sdb1

# 或使用fuser命令
fuser -m /dev/sdb1

# 然后杀死相关进程或关闭相关程序
场景2:端口被占用无法启动服务
# 查看占用8080端口的进程
lsof -i :8080

# 如果是非关键进程,可以杀死它
kill $(lsof -t -i :8080)

# 或者查看进程详情再做决定
ps -p $(lsof -t -i :8080)
场景3:磁盘空间不足但找不到大文件
# 查看被删除但仍被进程占用的文件(空间未释放)
lsof | grep deleted

# 输出示例:
# nginx 1234 root 4w REG 253,0 1000000000 123456 /var/log/nginx/access.log (deleted)
# 这种文件虽然已被删除,但进程仍持有文件描述符,空间不会释放
# 解决方法:重启相关进程或发送信号让其重新打开日志文件
注意事项:
  • lsof需要root权限才能查看所有进程信息
  • 输出可能非常庞大,建议配合grep等命令过滤
  • 使用-nP选项可以加速网络连接查询
  • 注意"deleted"状态的文件,它们占用空间但不可见
  • lsof可能影响系统性能,生产环境谨慎使用
  • 某些选项需要较新版本的lsof支持

安装lsof

大多数Linux发行版默认安装lsof,如果需要安装:

# Ubuntu/Debian
sudo apt-get install lsof

# CentOS/RHEL/Fedora
sudo yum install lsof

# Arch Linux
sudo pacman -S lsof

# 验证安装
lsof -v
或
which lsof

性能优化技巧

查询优化
  • 尽量缩小查询范围(使用-p、-u、-c等)
  • 使用-t选项只获取PID
  • 避免在生产环境高峰时段执行
  • 使用-nP避免DNS和端口解析
输出过滤
  • 管道配合grep进行过滤
  • 使用awk进行字段提取
  • 使用sort和uniq去重统计
  • 重定向到文件分析

相关命令

fuser

查看文件或套接字的进程

查看详情
netstat/ss

网络连接和统计信息

查看详情
strace

跟踪系统调用和信号

查看详情