lsof命令

lsof 命令 #

lsof(List Open Files)是一个强大的命令行工具,用于列出系统上当前打开的文件。在Unix/Linux系统中,几乎所有事物都被视为文件,包括普通文件、目录、块设备、网络套接字等。因此,lsof可以提供有关进程、用户和系统活动的宝贵信息。

语法 #

lsof [选项]

常用选项 #

选项 描述
-a 使用AND逻辑组合多个选项(默认为OR逻辑)
-c 命令 列出指定命令打开的文件
-d FD列表 列出指定文件描述符的文件
-i [协议][@主机][:端口] 列出符合指定网络条件的文件
-p PID列表 列出指定进程ID打开的文件
-u 用户列表 列出指定用户打开的文件
-t 仅输出进程ID
+D 目录 列出指定目录及其子目录下打开的文件
-n 不将网络地址转换为主机名
-P 不将端口号转换为服务名
-r 秒数 重复执行,每隔指定秒数
-l 不显示用户ID的用户名
-F 格式 指定输出格式,用于脚本处理
-s [协议:状态] 列出指定协议和状态的网络文件
-T 显示TCP/TPI信息
-U 列出Unix域套接字
-V 显示版本信息
-h, --help 显示帮助信息

输出字段说明 #

lsof的默认输出包含以下列:

  • COMMAND:进程的命令名(可能被截断)
  • PID:进程ID
  • USER:进程所有者的用户名
  • FD:文件描述符
    • cwd:当前工作目录
    • rtd:根目录
    • txt:程序文本(代码和数据)
    • mem:内存映射文件
    • 0u, 1u, 2u:标准输入、输出和错误(u表示读写模式)
    • 数字后跟模式:r(读)、w(写)、u(读写)
  • TYPE:文件类型
    • REG:常规文件
    • DIR:目录
    • CHR:字符特殊文件
    • BLK:块特殊文件
    • UNIX:UNIX域套接字
    • FIFO:命名管道
    • IPv4/IPv6:网络文件
  • DEVICE:设备号(主设备号,次设备号)
  • SIZE/OFF:文件大小或偏移量
  • NODE:文件的索引节点号
  • NAME:文件的实际名称或路径

常见用法 #

1. 列出所有打开的文件 #

lsof

由于输出可能非常多,通常会与其他命令或选项结合使用。

2. 列出特定进程打开的文件 #

lsof -p 1234

这将显示PID为1234的进程打开的所有文件。

3. 列出特定用户打开的文件 #

lsof -u username

4. 列出特定命令打开的文件 #

lsof -c nginx

这将显示所有名称以"nginx"开头的进程打开的文件。

5. 列出特定文件被哪些进程打开 #

lsof /path/to/file

6. 列出特定目录及其子目录下被打开的文件 #

lsof +D /var/log

7. 列出网络连接 #

lsof -i

8. 列出特定端口的连接 #

lsof -i :22

这将显示所有与22端口(通常是SSH)相关的连接。

9. 列出特定协议的连接 #

lsof -i tcp
lsof -i udp

10. 列出特定主机的连接 #

lsof -i @192.168.1.1

11. 列出被删除但仍被进程打开的文件 #

lsof +L1

这对于查找占用磁盘空间但已被删除的文件很有用。

12. 组合多个条件(AND逻辑) #

lsof -a -u username -i tcp

这将显示指定用户打开的TCP连接。

实用示例 #

1. 查找占用特定端口的进程 #

lsof -i :80

这将显示占用80端口(HTTP)的进程。

2. 查找哪个进程正在写入特定文件 #

lsof -t /var/log/syslog

-t选项只输出进程ID,便于在其他命令中使用。

3. 查找被删除但仍占用空间的日志文件 #

lsof | grep '(deleted)' | grep '\.log'

4. 监控文件系统活动 #

lsof -r 5 /home

这将每5秒显示一次/home目录下的文件活动。

5. 查找特定用户的网络活动 #

lsof -a -u username -i

6. 查找进程使用的共享库 #

lsof -p 1234 | grep '\.so'

7. 查找正在访问特定设备的进程 #

lsof /dev/sda1

8. 查找监听端口的进程 #

lsof -i -sTCP:LISTEN

9. 查找已建立的网络连接 #

lsof -i -sTCP:ESTABLISHED

10. 查找特定进程的网络连接 #

lsof -a -p 1234 -i

11. 查找打开特定类型文件的进程 #

lsof -a -u username -d 0,1,2

这将显示指定用户打开的标准输入、输出和错误文件。

12. 查找内存映射文件 #

lsof -a -p 1234 | grep mem

高级用法 #

1. 格式化输出(用于脚本处理) #

lsof -F pcfn -p 1234

这将输出进程ID(p)、命令名(c)、文件描述符(f)和文件名(n),每个字段前面有一个字符标识符。

2. 查找特定时间段内打开的文件 #

lsof -N -a -d ^cwd,^rtd,^txt,^mem -mtime -1

这将显示过去24小时内打开的文件。

3. 查找特定用户组打开的文件 #

lsof -g 1000

这将显示GID为1000的组的进程打开的文件。

4. 查找特定进程树打开的文件 #

lsof -R -p 1234

-R选项显示父进程ID(PPID)。

5. 查找NFS挂载点上的活动 #

lsof -N /mnt/nfs

6. 查找IPv6连接 #

lsof -i 6

常见问题排查 #

1. 查找占用磁盘空间的已删除文件 #

lsof | grep -i deleted | grep -v "\.so" | sort -nrk 7

这将显示已删除但仍被进程打开的文件,按大小排序,排除共享库文件。

2. 查找无法卸载设备的原因 #

lsof /mnt/device

这将显示哪些进程正在使用该挂载点,阻止卸载。

3. 查找内存泄漏 #

lsof -p 1234 | wc -l

重复执行此命令,如果打开的文件数量持续增加,可能表明存在内存泄漏。

4. 查找网络问题 #

lsof -i | grep -i estab

这将显示所有已建立的网络连接,有助于诊断网络问题。

5. 查找文件锁 #

lsof /path/to/file | grep LOCK

与其他工具的结合 #

与grep结合 #

lsof | grep pattern

与kill结合 #

kill -9 $(lsof -t /path/to/file)

这将终止所有打开指定文件的进程。

与watch结合 #

watch -n 1 "lsof -i :80"

这将每秒监控一次80端口的活动。

提示 #

  • 使用-a选项组合多个条件(AND逻辑),默认是OR逻辑
  • 使用-n-P选项可以加快执行速度,因为不需要解析主机名和服务名
  • 对于大型系统,lsof可能需要较长时间执行,考虑使用更具体的选项限制输出
  • 使用-r选项可以持续监控文件活动
  • 在脚本中使用-t选项只输出进程ID,便于进一步处理
  • 使用-F选项可以生成更易于脚本处理的输出格式
  • 对于网络连接,使用-i选项可以提供详细信息
  • 使用+D而不是grep来查找目录中的文件,因为它会递归搜索子目录
  • 在处理大量输出时,考虑使用sortuniqwc等命令进行进一步分析