Varidata 新闻资讯
知识库 | 问答 | 最新技术 | IDC 行业新闻
Varidata 知识文档

如何使用 fuser 识别占用端口的进程

发布日期:2026-11-05
fuser 显示占用 TCP 端口的进程

你启动服务时,终端却立刻返回:address already in use。说明该端口已被其他程序抢先占用,在找到它之前,你的应用无法绑定这个端口。

在 Linux 上,fuser 是找出繁忙端口背后 PID 的最快方法。只需一行命令就能得到答案:运行 fuser -v -n tcp [port],即可查看占用该端口的用户和进程 ID。

假设端口 3000 已经被占用。你可以用 fuser 在几秒钟内查清楚。本文将向你展示如何找出是谁在使用该端口、如何检查 UDP 端口是否已被占用,以及在采取下一步操作之前如何正确解读输出结果。

理解 fuser 命令

fuser 的作用及其来源

fuser 是 Linux 上的一个命令行工具,用于识别当前正在使用某个文件、目录、套接字或文件系统的进程。它的名字是 “file user” 的缩写,这也解释了它用途广泛的原因。你可以将它指向一个被锁定的文件、一个已挂载的目录,或者一个网络套接字,它都会告诉你是谁在占用它。根据 Ostechnix 的说法,该工具会提供每个进程的详细信息,包括所属用户、进程 ID、访问类型以及所使用的命令。

你通常可以在 psmisc 软件包中找到 fuser,而大多数 Linux 发行版都会自带该软件包。这一点对排障非常重要。因为该工具通常已经存在于系统中,所以你无需额外安装任何新软件,就能诊断端口被占用的问题。Ostechnix 指出,fuser 在文件锁定、进程管理和系统资源问题排查方面尤其有用。

用于端口检查的基本语法

-n 参数用于告诉 fuser 要搜索哪个命名空间,你可以传入 tcp 或 udp 作为协议。你也可以使用 port/protocol 这种简写形式,例如 22/tcp,把端口号和协议合并为一个参数。这两种写法都可以,选择你觉得在记录中更清晰的方式即可。

默认输出非常简洁。fuser 只会返回 PID,并以空格分隔,不带任何标签。这对脚本很方便,但人眼阅读并不友好。加上 -v 参数后,你会得到一个更详细的输出表,其中包含四列:

列名

含义

USER

进程的所属用户

PID

进程 ID

ACCESS

访问类型,例如 f 表示打开的文件,c 表示当前目录

COMMAND

命令名称

详细输出真正回答了核心问题:不仅是哪个 PID 占用了端口,还包括是哪个用户、哪个程序。采取操作前,请先读清这一行。

如何使用 fuser 检查端口

识别哪个进程正在监听某个特定端口

先来看一个具体场景。假设某个服务启动失败,因为端口 8002 已被其他程序占用。运行 fuser -v -n tcp 8002,然后阅读它打印出的表格。USER 列显示拥有该进程的账户。PID 列给出你需要的进程 ID。ACCESS 列说明该进程如何访问这个套接字,其中可能会出现 f 之类的标记,表示它以文件方式打开该套接字。COMMAND 列则显示程序本身的名称。

这一行信息就足够说明一切:是谁启动了它、它是什么程序,以及你接下来该如何处理。你可以用这种方式检查任意端口,通常不到一秒就能得到结果。

简写形式的效果完全一样。你不必分开写参数,而是可以把端口和协议直接写在一起。VMware Photon 的文档清晰展示了这种写法:

请把该输出理解为一份纯 PID 列表。左侧标签表示套接字,右侧数字则是附着在其上的进程。多个数字说明有多个进程共享同一个套接字,这在会派生多个工作进程的 Web 服务器中很常见。要找出某个特定端口上正在监听的进程/服务,在大多数情况下你通常只需要第一个数字。

协议非常重要。TCP 检查不会显示 UDP 监听器,反过来也一样。因此务必让参数与实际流量类型匹配。如果你不确定,就把两种都查一遍。这正是在 Linux 中查找哪个进程或服务正在监听某个特定端口的核心习惯:先确认协议,再确认端口。

正确解读输出结果

详细输出表值得你仔细阅读。标记为 f 的进程表示它将该套接字作为文件保持打开状态。标记为 c 的进程则表示它位于那个目录中。对于网络检查来说,你通常最关注的是 PID 和 COMMAND 这两个字段的组合。

简写形式能减少输入量。运行 sudo fuser 80/tcp 会返回一个纯 PID 列表,适合脚本或快速查看。-v 参数则更适合人来阅读。根据你是要立即处理,还是仅记录结果,来选择对应方式。

还有一个区别也很有帮助。某个运行在该端口上的进程,可能只是一个客户端连接,而不一定是服务端监听程序。详细输出会显示命令名称,因此你可以分辨它是浏览器还是守护进程。这种上下文信息能帮助你避免后续做出代价高昂的误判。

终止占用端口的进程

使用 fuser 发送信号

有时你识别出某个进程后,会决定必须把它结束掉。fuser 命令可以直接替你发送信号。加上 -k 参数后,工具会终止所有附着在该套接字上的进程。典型命令形如 fuser -k port/tcp,其中你需要把占位符替换成实际端口号。比如某个服务卡在端口 3000 上,你可以运行 fuser -k 3000/tcp。该工具默认发送 SIGKILL,也就是立即强制结束进程,不给任何清理机会。对于生产环境中的服务来说,这种默认行为相当激烈。程序没有机会刷新缓冲区,也无法正常关闭文件。

你也可以选择更温和的信号。-SIGNAL 选项允许你指定要发送的信号。例如,加上 -TERM 表示请求进程优雅退出。这样程序就有机会关闭文件并释放资源。只有当优雅停止失败时,再使用 SIGKILL。一个较好的顺序是先发 TERM,稍等片刻,如果进程仍然存在,再发 KILL。把 -k 和 -v 结合起来还能让你看到工具的执行过程。详细模式会打印出每个收到信号的 PID。操作之后请检查退出状态。返回值为 0 表示信号已成功送达目标。

-k 参数既可以与命名空间参数一起使用,也可以和套接字参数一起使用。你可以写成 fuser -k -n tcp 8080,也可以使用简写 fuser -k port/tcp。这两种方式针对的是同一个进程。简写在终端中处理繁忙端口时读起来更快;长写法则在脚本中更易于自我说明。选择适合你工作流的风格即可。

执行 kill 前的安全检查

误杀错误的进程可能会导致服务中断、活动连接掉线,甚至打断数据库写入。执行操作前,先确认两件事:PID 和命令名称。发送信号前请先运行详细检查。认真查看 USER、PID 和 COMMAND 列。问问自己:这个程序是否本来就应该在运行?一个 Web 服务器占用某个繁忙套接字是正常现象;而一个陌生二进制文件占着端口,则更值得调查,而不是立刻发送 kill 信号。如果命令名称看起来不熟悉,请用 ps -p PID -o comm= 进行交叉验证。操作前把 PID 记录下来。如果后续服务出现故障,这份记录会很有帮助。

永远不要对一个尚未核实的 PID 执行 kill 命令。详细输出存在的意义,正是为了避免这种错误。

权限同样很重要。你只能向自己拥有的进程发送信号。在共享 Linux 服务器上,其他用户的守护进程会拒绝你的信号。给命令加上 sudo 前缀,就能获得所需权限。系统会提示你输入密码,然后再发送该信号。如果没有这个前缀,工具会报错,而且不会发生任何事情。

还有一个习惯也很有帮助:检查该进程是否会自动重启。很多服务都运行在某个 supervisor 的管理之下,几秒钟内就会被重新拉起。杀掉这样的进程,只会短暂释放端口,随后同一个程序又会再次占用它。你需要先停止 supervisor,否则这个循环会不断重复。不然你会一直追着同一个问题跑。kill 完成后,请再次执行详细检查,以确认端口已经释放。

故障排查与交叉验证

当 fuser 没有返回任何结果时

空结果并不总是意味着端口是空闲的。最常见的原因是协议不匹配。你检查的是 TCP,但实际占用该套接字的是一个 UDP 服务。在下结论之前,请使用另一种协议再查一次。

IPv6 是下一个常见“坑”。绑定在 IPv6 协议栈上的服务,可能不会出现在 IPv4 的查询结果中,反之亦然。如果 “port already in use” 错误仍然存在,请测试两种地址族。

权限问题则是最后一个常见原因。属于其他用户的进程,对你的账户来说可能是不可见的。给命令加上 sudo,再重新查询一遍。你可以用 fuser 快速检查,但如果得到空结果,值得再多做一步确认。

使用 lsof 和 netstat 进行交叉检查

验证能避免误判,另外两个工具可以为你提供第二意见。OneUptime 博客用一张简洁的参考表记录了这些常用命令:

工具 / 命令

用途

sudo netstat -tulnp

列出所有正在监听的端口及其进程信息(TCP 和 UDP)

sudo netstat -tlnp | grep ':8080 '

查找某个特定端口上的进程

sudo lsof -i :80

显示所有正在使用 80 端口的进程

sudo lsof -i TCP:22

按特定协议和端口进行查询

当你需要更易读的结果时,可以先从 lsof -i :3000 开始。它的输出会在一行中给出命令名、用户和 PID。加上 -t 参数后,则只返回 PID 列表:lsof -t -i :3000 很适合脚本和 kill 命令。当 netstat 在非 root 账户下无法显示进程详情时,OneUptime 建议使用 ss -tulpn | grep :3000 作为替代方案。

这些习惯在任何 Linux 服务器上都很重要。要找出某个特定端口上正在监听的进程/服务,请用第二个工具再确认一次。相同的原则也适用于你在繁忙主机上调查某个特定端口时。对某个端口做交叉验证只需要几秒钟,却可以帮助你发现协议或权限带来的盲点。这才是在 Linux 中有把握地确认某个特定端口监听情况的实用做法。

现在,你已经掌握了一套可重复使用的繁忙套接字排查流程:

  1. 找出绑定失败的端口。

  2. 运行 fuser -v -n tcp [port],获取 PID、用户和命令名称。

  3. 决定是终止该进程,还是让它继续运行。

该工具在几乎所有 Linux 系统中都随 psmisc 软件包一起提供,因此你可以在无需安装额外软件的情况下,使用 fuser 检查端口。这使它非常适合用于快速的服务器故障排查。

在终止进程之前务必先进行核实。查看命令名称,确认所属用户,并检查是否存在会自动重启服务的 supervisor。一次谨慎的检查,可以帮助你避免业务中断。

常见问题

fuser 在所有 Linux 发行版上都能使用吗?

大多数发行版都会将 fuser 包含在 psmisc 软件包中,因此通常系统里已经有了。如果命令执行失败,可以先用 which fuser 检查是否存在。某些极简容器镜像可能不会包含 psmisc,这时你可以安装它,或者改用 lsof。

为什么 fuser 只显示 PID,却不显示命令名称?

因为你没有加详细模式参数。默认输出只会列出 PID。加上 -v 后,就能看到每个进程的用户、访问类型和命令名称。这些额外上下文有助于你在发送信号前确认程序身份。

我可以用同样的命令检查 UDP 端口吗?

可以。只需替换协议参数:fuser -v -n udp [port]。TCP 查询不会显示 UDP 监听器,因此参数必须与流量类型匹配。如果不确定,就把两种都检查一遍。

运行 fuser 一定需要 root 权限吗?

不一定,但权限会影响你能看到的内容。你自己的进程无需提权也能看到。其他用户的进程则只有在加上 sudo 后才会显示。向某个特定进程持有者发送信号时,同样遵循这一规则。

如果 fuser 和 lsof 的结果不一致怎么办?

不要盲信任何一个。先重新检查协议和地址族,然后再用 ss -tulpn 做比较。陈旧条目或权限差异都可能导致结果不一致。在对 Linux 上的进程采取操作之前,请先使用 ps -p [PID] 再次确认 PID。

您的免费试用从这里开始!
联系我们的团队申请物理服务器服务!
注册成为会员,尊享专属礼遇!
您的免费试用从这里开始!
联系我们的团队申请物理服务器服务!
注册成为会员,尊享专属礼遇!
Telegram Teams