Linux文件与进程交互的窥探者lsof

lsof 是一个 Linux 和 UNIX 系统中的实用工具,用于列出系统中打开文件的所有信息。这个名字代表 “List Open Files”,但它也可以显示进程相关的其他信息,如:

打开的文件描述符列表
打开网络连接的列表
被进程使用的信号和内核对象等

在Linux系统中,有一个经典的概念:
一切皆文件”(Everything is a file),而lsof是一个列出当前系统打开文件的工具。这个命令可以列出被进程打开的文件、网络连接、设备、文件描述符等信息,帮助用户了解系统资源的使用情况。

命令及常用参数
语法格式:lsof [options] filename

1.1 常用参数

-p<进程PID>: 输出指定pid的进程打开的文件;

-l:使用用户ID代替输出中的用户名;

-u<用户名> : 输出指定用户打开的文件;

-c <字符串>: 过滤出 COMMAND 列中包含 指定字符的记录;

-d<文件描述符>: 输出包含指定文件描述符(FD列)的项;

-n :禁止解析主机名;

-i : 输出符合指定条件的项

-i [4|6] :分别指 IPv4、IPv6

-i [TCP|UDP]:指 TCP 或 UDP连接;

-i @[hostname |hostaddr]:指 主机名或地址;

-i:port : 端口号,可以是多个。

1.2 输出列含义

在这里插入图片描述

常用场景
2.1 监控主机当前打开文件句柄总量

当Linux系统中的文件句柄数量达到上限时,可能会引发一系列风险和问题,如程序崩溃、系统资源耗尽、主机性能下降等。

以suse系统为例:

#/bin/bash
#################文件句柄监控###################
#####全局变量#####
threshold_value_user="40000"
threshold_value_system="50000"
username=`whoami`
ip_addr=`ip addr show | grep 'inet ' | grep -v '127.0.0' | awk '{print $2}' | cut -d/ -f1|head -1`
#####判断当前主机系统版本#####
system_version=`cat /etc/SuSE-release|grep VERSION|awk -F"=" '{print $2}'`
system_leven=`cat /etc/SuSE-release|grep PATCHLEVEL|awk -F"=" '{print $2}'`
##根据系统信息执行句柄数统计命令
if [ ${system_version} -eq 12 -a ${system_leven} -ge 4 ];then
    handle_user=`lsof -Ki -u ${username}|wc -l`
    handle_system=`lsof -Ki|wc -l`
else
    handle_user=`lsof -u ${username}|wc -l`
    handle_system=`lsof|wc -l`
fi
#####告警发送#####
if [ ${handle_user} -ge ${threshold_value_user} ];then
msg1="【告警】:${ip_addr};${username}用户下的文件句柄数量达到${handle_user},请核查!"
fi

if [ ${handle_system} -ge ${threshold_value_system} ];then
    msg2="【告警】:${ip_addr}系统文件句柄数总量达到${handle_system},请核查!"
fi
……

以centos为例子:

在 CentOS 上,你可以使用 lsof 命令结合其他工具来监控主机当前打开的文件句柄总量。但是,需要注意的是,lsof 本身并不直接提供一个选项来显示打开的文件句柄总量。不过,你可以通过一些间接的方法来获取这个信息。

一种方法是使用 lsof 命令结合 wc(word count)命令来统计打开的文件句柄数量。例如:

bash
lsof | wc -l
这个命令会列出所有打开的文件,并使用 wc -l 来计算行数。请注意,这个方法可能会包括一些额外的行,比如标题行,所以得到的结果可能会比实际的文件句柄数量稍高一些。

另一种更精确的方法是使用 /proc/sys/fs/file-max 文件来查看系统允许的最大文件句柄数量,以及 /proc/sys/fs/file-nr 文件来查看当前已分配的文件句柄数量。例如:

bash
cat /proc/sys/fs/file-nr
这个命令会输出三个值,分别是:

已分配的文件句柄数量
已分配但尚未使用的文件句柄数量
系统允许的最大文件句柄数量
你关注的是第一个值,即已分配的文件句柄数量。这个值表示当前系统中所有进程打开的文件句柄总数。

如果你想要实时监控这个值,你可以使用 watch 命令来周期性地运行上述命令并查看结果:

bash
watch -n 1 cat /proc/sys/fs/file-nr
这个命令会每秒更新一次输出,让你能够实时看到文件句柄数量的变化。


2.2 查找文件句柄未释放进程以及文件恢复

日常运维中经常遇到磁盘空间被占用,du查看文件实际大小小于文件系统使用率,此现象一般文件句柄未释放导致,可以通过lsof查找指定进程后,重启释放空间;

查找文件句柄未释放:

lsof |grep delete |sort -k7 -nr |head -20

删除文件恢复:

上述句柄未释放的文件,也可手动恢复:通过lsof找出需要恢复的文件信息,根据信息中的PID和FD信息,找到/proc/${PID}/${FD}下的文件,在重定向恢复文件即可。

图片

卸载文件系统时繁忙无法卸载,也可通过lsof查出进程占用,通过停止对应进程后再进行卸载。

2.3 常用查找进程与文件命令

查看指定文件被哪些进程打开:lsof /path/file

查看指定端口被什么进程占用:lsof -i:protNumber

查看指定用户打开的文件:lsof -u username

查看指定进程打开的文件:lsof -p pid

查看指定目录下被打开的文件:lsof +D /path/directory

查看套接字和网络连接:lsof -i
列出所有打开的文件:

lsof
列出特定进程打开的文件:

lsof -p <进程ID>
列出特定用户打开的文件:

lsof -u <用户名>
列出特定文件被哪些进程使用:

lsof /path/to/file
列出特定网络端口被哪些进程使用:

lsof -i :<端口号>
列出特定进程使用的信号:

lsof -p <进程ID> | grep REG
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酱江奖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值