这是关于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提供了两种查询方式:
sudo lsof +D /path/to/dir
:递归查看目录及其子目录下被打开的文件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诊断?
文件描述符泄漏可以通过以下步骤诊断:
首先找到可疑进程的PID,比如一个Java应用:
pgrep -f java
查看该进程当前打开的文件描述符数量:
sudo lsof -p 830198| wc -l
实时监控FD数量变化:
watch -n 1 "sudo lsof -p 830198 | wc -l"
如果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可以分步骤协助调查:
首先检查所有ESTABLISHED状态的网络连接:
sudo lsof -i -sTCP:ESTABLISHED -nP
重点关注非常规外连(如连接到矿池或陌生IP):
sudo lsof -i -nP | grep -E '>(1.1.1.1|2.2.2.2)'
检查是否有进程打开了异常文件(如/etc/shadow):
sudo lsof /etc/shadow
查看可疑进程(如非root用户运行的/bin/bash):
sudo lsof -c bash | grep -v root
检查已删除但仍被打开的文件(可能隐藏后门):
sudo lsof | grep deleted | grep -E '\.so|bin'
最后可以将可疑进程的完整资源使用情况保存供进一步分析:
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:文件路径或网络连接详情