cxl
Published on 2025-08-16 / 11 Visits
0
0

Linux命令-lsof

这是关于Linux系统运维范畴相关的面试题了,如果你是一名纯粹的Java后台开发,那恭喜你,应该也许大概率不会遇到这道题。

问题:

首先问了一下如何查看当前内存与cpu使用情况,然后如何查看进程使用情况,比如该进程都打开了哪些文件,应该用什么命令?

思路:

工作十余年来一直用的就是linux环境部署服务应用,在linux命令这块还是蛮有信心的,毕竟小到mysql大到k8s这种复杂的软件环境都部署过了。谁知还是栽了跟头,ps -ef 命令查看进程列表倒是用得滚瓜烂熟,但是进程详情或是打开了哪些文件?(虽然面试官对它的问题其实也没有表达的那么清楚)一时脑海里竟找不到合适的记忆,这就。。。。。。

于是面试结束后的我痛定思痛,查阅了一番资料之后,终于明白面试官想考的是啥命令了:lsof

答案:

lsof 全称是"List Open Files",用于列出Linux/Unix系统中所有被进程打开的文件及相关信息。在Linux哲学中"一切皆文件",因此lsof不仅能显示常规文件,还能列出目录、网络连接(TCP/UDP套接字)、设备文件、管道和共享库等资源。它的核心价值在于帮助管理员诊断"文件被占用"错误、定位资源泄漏元凶、分析网络连接和端口冲突等问题。所以查看进程详情或占用了哪些文件可使用 lsof -p #pid

之前对这个命令可以说只是一面之缘,但深入了解了一番之后,才知道如此强大,绝对称得上是运维利器啊!不,瑞士军刀!!

延伸:

lsof安装
  • Debian/Ubuntu系系统:sudo apt install lsof

  • RHEL/CentOS系系统:sudo yum install lsof

  • 较新的Fedora或openEuler系统:sudo dnf install lsof

lsof用法
lsof最基本的用法是什么?如何查看系统中所有打开的文件?

最基础的命令是直接输入lsof,这将列出系统中所有进程打开的所有文件资源,但此举输出信息量巨大,要仔细甄别,我一打印这个命令屏幕直接就是刷刷刷,按ctrl+c都拦不住啊,于是就加了个 | more ,一页一页看,如果有需要的话,主要用法

  sudo lsof -u root    # 查看root用户打开的文件
  sudo lsof -c nginx   # 查看所有nginx进程打开的文件
  sudo lsof -p 1234    # 查看PID为1234的进程打开的资源

除了普通文件,目录被占用的情况也很常见。如何用lsof处理?

对于目录占用问题,lsof提供了两种查询方式:

  1. sudo lsof +D /path/to/dir:递归查看目录及其子目录下被打开的文件

  2. sudo lsof +d /path/to/dir:仅查看该目录(不递归子目录)下的打开文件

例如,当无法卸载/mnt/usb设备时,可以运行:

  sudo lsof +D /mnt/usb    #  这将显示所有阻止卸载的进程,通常包括shell的当前工作目录(cwd)或某些进程打开的文件
假设我启动服务时遇到"Address already in use"错误,如何用lsof找出占用端口的进程?
  sudo lsof -i :端口号
  sudo lsof -i :端口号 -nP  # 避免DNS解析和端口服务名转换,即直接显示ip
  sudo lsof -i TCP -sTCP:LISTEN  # 查看所有TCP监听端口
  sudo lsof -i -sTCP:ESTABLISHED # 查看所有已建立的TCP连接
  sudo lsof -i @IP地址   # 针对特定IP地址的过滤

当磁盘空间显示不足,但通过du命令找不到大文件时,可能是什么原因?如何用lsof诊断?

这种情况通常是由于文件被进程打开后又被删除,导致空间未被释放。lsof可以查找这类"已删除但未释放"的文件

  sudo lsof +L1  # 显示链接数小于1的文件
  或
  sudo lsof | grep deleted  # 结果较多

文件描述符泄漏是另一个常见问题。如何用lsof诊断?

文件描述符泄漏可以通过以下步骤诊断:

  1. 首先找到可疑进程的PID,比如一个Java应用: pgrep -f java

  2. 查看该进程当前打开的文件描述符数量:sudo lsof -p 830198| wc -l

  3. 实时监控FD数量变化:watch -n 1 "sudo lsof -p 830198 | wc -l"

  4. 如果FD数量持续增长且不释放,基本可以确认存在泄漏。进一步分析可以查看打开的文件类型:sudo lsof -p 830198 -a -d 3-999 # 排除stdin/out/err后查看自定义FD 常见的泄漏点包括未关闭的日志文件、数据库连接、网络套接字等

演示一下如何用lsof进行组合查询?比如同时满足多个条件的情况。

lsof的-a选项可以实现AND逻辑组合查询。例如,要查找用户server打开的TCP连接状态为ESTABLISHED:

  sudo lsof -u server -a -sTCP:ESTABLISHED -nP
  sudo lsof -i :80 -a -c ^nginx -nP  # 这里^nginx表示排除进程名包含nginx的进程
  sudo lsof -u nginx -a +D /var/www -a -i  # 查看nginx用户在/var/www目录下打开的文件及其网络连接

某台服务器发现异常外连,怀疑被入侵,如何用lsof协助调查?

这种情况下,lsof可以分步骤协助调查:

  1. 首先检查所有ESTABLISHED状态的网络连接:sudo lsof -i -sTCP:ESTABLISHED -nP

  2. 重点关注非常规外连(如连接到矿池或陌生IP):sudo lsof -i -nP | grep -E '>(1.1.1.1|2.2.2.2)'

  3. 检查是否有进程打开了异常文件(如/etc/shadow):sudo lsof /etc/shadow

  4. 查看可疑进程(如非root用户运行的/bin/bash):sudo lsof -c bash | grep -v root

  5. 检查已删除但仍被打开的文件(可能隐藏后门):sudo lsof | grep deleted | grep -E '\.so|bin'

  6. 最后可以将可疑进程的完整资源使用情况保存供进一步分析:sudo lsof -p 可疑PID > /tmp/lsof_analysis.txt

lsof输出附录
  • COMMAND:进程名称(如nginx、java)

  • PID:进程ID,用于精准操作目标

  • USER:进程所有者,判断权限问题

  • FD:文件描述符,核心分析字段:

    • cwd:当前工作目录

    • rtd:根目录

    • txt:程序代码段

    • mem:内存映射文件

    • 数字:文件描述符编号

    • 后缀字符:r(读)、w(写)、u(读写)、W(写锁定)

  • TYPE:文件类型:

    • REG:普通文件

    • DIR:目录

    • IPv4/IPv6:网络套接字

    • CHR:字符设备

    • unix:UNIX域套接字

  • DEVICE:设备号(主设备号,次设备号)

  • SIZE/OFF:文件大小/偏移量

  • NODE:文件的inode编号

  • NAME:文件路径或网络连接详情


Comment