Linux fuser 命令全解析,运维排障效率翻倍

在 Linux 服务器运维的日常中,“资源被占用”是最让人头疼的问题之一。想卸载数据盘,终端弹出device is busy;想重启 Nginx,提示address already in use;想删除日志文件,却被告知“文件正在被使用”。此时,你不需要逐个排查进程,也不用翻遍日志,fuser 就是解决这类问题的“瑞士军刀”。
作为 Linux 内置的进程定位工具,fuser 最大的优势在于反向追踪——它能通过文件、目录、挂载点或网络端口,精准找出所有正在使用它们的进程,甚至能直接执行清理操作。本文整合了基础原理、参数详解与实战场景,摒弃晦涩的官方术语,用一线运维的视角,带你彻底吃透 fuser,解决 90%的“占用类”排障问题。
一、先搞懂:fuser 到底能做什么?
fuser 的全称可以理解为 File User(文件使用者),它的核心逻辑是“以资源为中心,找进程”,这与我们常用的 ps(以进程为中心,找资源)恰好相反。
在 Linux 中,fuser 属于 psmisc 工具包,系统默认预装,无需手动安装。它的核心能力可分为三大类,覆盖运维全场景:
- 文件/目录维度:找出谁在读写某个文件、谁把某个目录设为了当前工作目录;
- 文件系统维度:找出所有占用某个挂载点(如 /data)的进程,解决“无法卸载”问题;
- 网络端口维度:找出占用某个 TCP/UDP 端口的进程,解决“服务启动失败”问题。
与同类工具(如 lsof)相比,fuser 的优势是轻量、高效、命令简洁,尤其适合快速排障和脚本自动化场景。
二、基础入门:从零开始用 fuser
在深入参数之前,先掌握 fuser 的最基础用法,建立核心认知。
(一)最简用法:直接查询资源占用
语法:fuser [资源路径/端口]
# 查看 /root/test.sh 被哪些进程占用 fuser /root/test.sh # 查看 8080 TCP 端口被哪些进程占用 fuser 8080/tcp
典型输出:
/root/test.sh: 12345e 12346f
输出结果分为两部分,缺一不可:
- 数字部分(12345、12346):占用资源的进程 PID;
- 后缀字母(e、f):进程对资源的访问类型——这是判断问题根源的关键,必须熟记。
(二)核心必记:访问类型字母含义
fuser 用单个字母标识进程的访问方式,默认只显示核心类型,完整类型如下(按使用频率排序):
| 字母 | 核心含义 | 运维场景解读 |
|---|---|---|
| c | 当前目录 | 进程把该目录设为了工作目录,删除目录会失败 |
| e | 执行中 | 进程正在运行该可执行文件,杀死进程会终止程序 |
| f | 只读打开 | 进程仅读取该文件(默认不显示) |
| F | 读写打开 | 进程正在写入该文件,强制删除会导致数据丢失(默认不显示) |
| m | 内存映射 | 进程将文件映射到内存(如共享库、缓存文件) |
| r | 根目录 | 进程把该目录设为了根目录(极少出现,多为容器进程) |
举个例子:如果输出是 12345c,说明 PID 为 12345 的进程,当前工作目录就是你查询的目录,此时删除该目录一定会失败。
三、核心参数详解:拒绝死记,理解着用
fuser 的参数不多,但每个都直击运维痛点。我们按“查询”“清理”“特殊场景”分类,结合实际用途讲解,避免孤立记参数。
(一)查询类参数:把信息查全、查准
这类参数用于优化查询结果,是排障的基础,优先掌握。
1. -v:详细模式(运维排障首选)
作用:以类似 ps 的格式输出,显示 PID、用户、进程命令、访问类型,一目了然。
语法:fuser -v [资源]
fuser -v /data/logs
输出示例:
USER PID ACCESS COMMAND /data/logs: root 1234 ..c.. bash nginx 5678 ..f.. nginx
优势:相比最简用法,能直接看到“谁在占用(USER)”“用什么程序占用(COMMAND)”,无需再用ps -p PID二次查询。
2. -u:显示进程所属用户
作用:在 PID 后追加用户名,快速定位“责任人”。
语法:fuser -u [资源]
fuser -u 80/tcp
输出示例:
80/tcp: 1234(root) 5678(nginx)
提示:如果同时使用 -v,-u 会被自动包含,无需重复添加。
3. -m:匹配整个文件系统(挂载点专用)
作用:查询指定挂载点或分区上的所有占用进程,而非单个文件/目录。
语法:fuser -v -m [挂载点/块设备]
# 查看 /mnt/data 挂载点的所有占用进程 fuser -v -m /mnt/data # 也可以直接指定块设备(如 /dev/sdb1) fuser -v -m /dev/sdb1
关键注意:使用-m时,fuser 会匹配整个文件系统,而非单个目录。比如查询/mnt/data/test,会自动识别为/mnt/data整个挂载点,这是解决“无法卸载”的核心参数。
4. -n:指定命名空间(查端口必备)
作用:明确查询的资源类型,支持 file(文件,默认)、tcp、udp。
语法:fuser -v -n [命名空间] [资源]
# 查 TCP 80 端口(完整写法) fuser -v -n tcp 80 # 查 UDP 53 端口(完整写法) fuser -v -n udp 53
简化写法(运维通用):直接用 端口/协议,省略 -n,更高效:
fuser -v 80/tcp fuser -v 53/udp
5. -4 / -6:限定 IP 协议版本
作用:仅查询 IPv4 或 IPv6 端口,避免混淆。
语法:fuser -v -4 [端口/协议] / fuser -v -6 [端口/协议]
# 仅查 IPv4 的 8080 TCP 端口 fuser -v -4 8080/tcp # 仅查 IPv6 的 8080 TCP 端口 fuser -v -6 8080/tcp
(二)清理类参数:安全杀死占用进程
这类参数用于终止占用进程,释放资源,属于高危操作,生产环境必须谨慎使用。
1. -k:杀死占用进程
作用:向占用进程发送信号,默认发送 SIGKILL(9 号信号,强制杀死)。
语法:fuser -k [资源]
# 强制杀死占用 8080 TCP 端口的进程 fuser -k 8080/tcp
警告:默认的 9 号信号会强制终止进程,可能导致数据丢失(如正在写入的数据库进程),生产环境优先用“优雅信号”。
2. -SIGNAL:自定义杀死信号(优雅清理)
作用:替代默认的 SIGKILL,使用指定信号终止进程,常用信号有两种:
- 15(SIGTERM):优雅退出,让进程完成收尾工作(推荐);
- 1(SIGHUP):重启进程(适合 Nginx、Redis 等服务)。
语法:fuser -k -[信号名/数字] [资源]
# 优雅杀死占用 /data 的进程(15 号信号) fuser -k -15 /data # 用信号名写法,更易读 fuser -k -TERM /data # 重启占用 80/tcp 的 Nginx 进程(1 号信号) fuser -k -HUP 80/tcp
3. -i:交互确认(防止误杀,生产必加)
作用:杀死进程前,会逐一询问是否确认,避免误杀核心进程(如 systemd、sshd)。
语法:fuser -k -i [资源]
# 确认后杀死占用 /mnt/data 的进程 fuser -k -i -m /mnt/data
输出示例:
/mnt/data: 1234 5678 Kill process 1234 (bash)? (y/N)
4. -w:仅杀死有写权限的进程
作用:只终止对资源有“写入权限”的进程,保留只读进程,适合需要保留服务的场景。
语法:fuser -k -w [资源]
# 仅杀死写入 /var/log/messages 的进程,保留只读查看的进程 fuser -k -w /var/log/messages
(三)特殊场景参数:脚本与排查辅助
1. -s:静默模式(脚本专用)
作用:不输出任何内容,仅通过返回值判断资源是否被占用(0=被占用,非 0=空闲)。
语法:fuser -s [资源]
# 脚本中判断 80 端口是否空闲 if fuser -s 80/tcp; then echo "80 端口已被占用" else echo "80 端口空闲,启动 Nginx" fi
2. -l:列出所有支持的信号名
作用:查询可用的杀死信号,避免记混数字,适合新手。
语法:fuser -l
3. -V:查看版本
作用:确认 fuser 版本,排查工具兼容性问题。
语法:fuser -V
四、一线实战场景:解决运维真实问题
理论参数最终要落地到场景,以下是 Linux 运维中最常见的 5 个场景,按“问题-排查-解决”的流程,给出可直接复制的命令。
场景一:卸载分区提示“device is busy”(最常见)
问题:执行umount /mnt/data时,提示 umount: /mnt/data: target is busy,无法卸载。
排查思路:找出占用该挂载点的所有进程,确认是否为核心进程,再清理。
操作步骤:
# 第一步:详细查看挂载点占用情况(必做,确认进程是否重要) sudo fuser -v -m /mnt/data # 第二步:优雅清理占用进程,加交互确认(生产环境) sudo fuser -k -i -15 -m /mnt/data # 第三步:再次尝试卸载 sudo umount /mnt/data # 若仍无法卸载,强制杀死(最后手段) sudo fuser -k -i -9 -m /mnt/data sudo umount /mnt/data
场景二:服务启动失败,提示“端口被占用”
问题:启动 SpringBoot 服务时,提示 Address already in use,占用端口为 8080。
排查思路:定位 8080 端口的占用进程,确认是残留进程还是其他服务,再清理。
操作步骤:
# 第一步:查看 8080 TCP 端口的详细占用情况 sudo fuser -v 8080/tcp # 第二步:若为残留进程,优雅清理 sudo fuser -k -15 8080/tcp # 第三步:启动服务 java -jar app.jar
场景三:日志文件无法删除,提示“正在被使用”
问题:执行 rm -rf nginx.log 时,删除失败,或删除后磁盘空间未释放(因为进程还在写入)。
排查思路:找出写入该日志的进程,重启进程让其切换日志,再删除。
操作步骤:
# 第一步:查看日志文件的占用进程(重点看 F 类型,即写入进程) sudo fuser -v nginx.log # 第二步:向 Nginx 发送重启信号,让其切换日志(不终止服务) sudo fuser -k -HUP $(cat /var/run/nginx.pid) # 或直接用 fuser 重启(如果只有一个 Nginx 进程占用) sudo fuser -k -HUP nginx.log # 第三步:此时日志文件已无进程写入,可安全删除 rm -rf nginx.log
场景四:自动化脚本中判断资源是否空闲
需求:编写定时备份脚本,备份前判断 /dev/sdb1 是否被挂载(是否被占用),空闲才执行备份。
脚本实现:
#!/bin/bash # 备份脚本:backup.sh MOUNT_POINT="/mnt/backup" DEVICE="/dev/sdb1" # 第一步:静默判断设备是否被占用 if fuser -s $DEVICE; then echo "$(date +%F_%T):设备 $DEVICE 正在被占用,备份终止" >> /var/log/backup.log exit 1 fi # 第二步:设备空闲,挂载并执行备份 sudo mount $DEVICE $MOUNT_POINT sudo cp -r /data/backup/* $MOUNT_POINT/ echo "$(date +%F_%T):备份完成" >> /var/log/backup.log # 第三步:卸载设备 sudo umount $MOUNT_POINT
场景五:批量清理多个端口的残留进程
需求:测试环境重启时,需要清理 80、443、8080、8090 四个 TCP 端口的残留进程,一键清场。
脚本实现:
#!/bin/bash
# 端口清理脚本:clean_ports.sh
PORTS=(80 443 8080 8090)
PROTOCOL="tcp"
for PORT in "${PORTS[@]}"; do
echo "正在清理 ${PORT}/${PROTOCOL} 端口..."
# 先查看,再交互优雅清理
sudo fuser -v ${PORT}/${PROTOCOL}
sudo fuser -k -i -15 ${PORT}/${PROTOCOL}
done
echo "端口清理完成!"
五、运维避坑指南:这些错误千万别犯
fuser 虽好用,但使用不当可能导致服务中断、数据丢失,以下是一线运维总结的 5 个核心避坑点,必须牢记:
- 权限不足会导致查询结果为空:普通用户只能查询自己的进程,查系统进程、端口、挂载点时,必须加 sudo。比如普通用户查 80 端口,会返回空,并非端口空闲,而是权限不够。
- -k 不要轻易用默认的 9 号信号:生产环境优先用 -15(SIGTERM)优雅退出,只有进程卡死时,才用 -9(SIGKILL)强制杀死。
- -m 参数会匹配整个文件系统:如果你想查单个目录,却用了 -m,会误杀整个分区的进程。比如 fuser -k -m /root/test,会杀死所有占用 / 分区的进程,直接导致服务器宕机!
- 内核进程无法被杀死:用 -v 查询时,若看到 COMMAND 列为 kernel,说明是内核进程占用(如磁盘缓存),fuser 无法杀死,也不要尝试杀死。
- 查端口时,避免混淆 TCP/UDP:比如查询 53 端口,要明确是 53/tcp(DNS 服务)还是 53/udp(DNS 解析),否则会查询不到。
六、速查清单:一键复制的常用命令
为了方便日常使用,将核心命令按场景整理为速查清单,可直接复制到服务器的 ~/.bashrc 中,或保存为 fuser_cheat.sh 备用。
(一)查询类(排障必备)
# 1. 详细查看文件/目录占用 sudo fuser -v /path/to/file_or_dir # 2. 详细查看挂载点/分区占用 sudo fuser -v -m /mnt/data # 3. 详细查看 TCP/UDP 端口占用 sudo fuser -v 80/tcp sudo fuser -v 53/udp # 4. 仅查看 IPv4 端口占用 sudo fuser -v -4 8080/tcp # 5. 查看进程访问类型(含只读/读写) sudo fuser -v -u /path/to/file
(二)清理类(安全优先)
# 1. 优雅杀死进程 + 交互确认(生产首选) sudo fuser -k -i -15 /path/to/file_or_dir # 2. 清理挂载点占用(卸载前) sudo fuser -k -i -15 -m /mnt/data # 3. 释放端口占用(优雅) sudo fuser -k -i -15 8080/tcp # 4. 强制杀死卡死进程(最后手段) sudo fuser -k -i -9 /path/to/file_or_dir
(三)脚本类(自动化)
# 1. 判断资源是否被占用
if fuser -s 80/tcp; then echo "端口被占用"; else echo "端口空闲"; fi
# 2. 批量清理端口
for port in 80 443 8080; do sudo fuser -k -i -15 ${port}/tcp; done
总结
fuser 是 Linux 运维中“小而美”的工具,它不追求复杂的功能,却能精准解决“资源被占用”的核心痛点。掌握它的关键,在于理解“资源→进程”的反向逻辑,熟记访问类型字母,以及坚持“先查询、再确认、后清理”的运维原则。
无论是日常排障、脚本自动化,还是应急处理,这份指南覆盖了从基础到实战的所有内容,建议收藏备用,让 fuser 成为你运维工作中的“得力助手”。
以上关于Linux fuser 命令全解析,运维排障效率翻倍的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Linux fuser 命令全解析,运维排障效率翻倍
微信
支付宝