dsh-port-guard:先判读再处置端口占用的 DSH 插件

前言

本地起 dev server,最常碰到的第一个障碍就是 EADDRINUSE: address already in use。在智能体工作流里,这个报错往往出现在任务最开头,而常见的处理方式很粗:直接 killall nodepkill -f node。结果是把机器上其他正常运行的 Node 服务一并杀掉。

但占着端口的进程不一定是该杀的:可能是自己上次会话遗留、还在正常服务的 dev server,也可能是别的项目或系统服务。也就是说,EADDRINUSE 有三条处置路径——复用、换端口、精确 kill——正确做法是先判断属于哪种,再决定动作。

dsh-port-guard 就是把这套判读流程做成插件的一个 DSH 工具。DSH(DeepSeek Harness)的理念是「一切皆插件」,下面介绍它的定位、功能和用法。

这是什么

dsh-port-guard 是一个 DeepSeek Harness 插件,作者是 PangYiMing,当前版本 0.1.0,许可证为 MIT。一句话定位:端口占用处置——对占端口的进程,按情况选择复用、换端口或精确 kill。

它解决的问题是:把「端口被占」从一次粗暴的 kill 变成一次有依据的判读,既不误杀别人的进程,也不白白重启自己还活着的 dev server。

核心功能

定位与取证

./scripts/port-guard.sh 8080

8080 换成实际被占的端口。脚本会打印占用进程的完整身份信息:先用 lsof 定位监听该端口的进程,再用 ps 查看启动时刻、运行时长、有无控制终端、%cpu 和 rss;用 lsof 的 cwd 定位进程属于哪个项目;最后用 pgrep 查子进程——有子进程的不要直接杀父进程,先看树。

判读组合

取证信息拿到后怎么判断?README 给出了几组典型判读:

  • PPID=1:父进程已退出,被 launchd 收养——孤儿进程
  • tty=??:没有控制终端,不是人在终端里跑的
  • fd0 → /dev/nullfd1/fd2 → 某个 .lognohup cmd > log 2>&1 & 的指纹,说明是 agent 或脚本拉起的
  • etime 好几天,加 %cpu 0.0,加 rss 极小:挂了很久的僵尸 watcher,可能一直 watch 着源码目录,某天突然醒来写产物
  • tty=ttys00X:人在终端窗口里起的,杀之前更应该问一声

三条处置路径

先判断属于哪种情况,再选对应动作,不无脑 kill。

路径 A,复用。占端口的是自己项目的 dev server,还在正常服务,复用比重启快。复用前先确认进程还活着,kill -0 只检测、不杀:

kill -0 "$PID" && echo alive

路径 B,换端口。占端口的是别人的项目或不该杀的进程,绕开即可,不抢杀:

PORT=18080 node index.js

路径 C,精确 kill。确认是僵尸或残留进程后,用插件的 kill 模式。它会先发 SIGTERM 给进程一个优雅退出的机会,不行再 SIGKILL:

./scripts/port-guard.sh 8080 --kill

安全红线

插件内置了五条红线,是设计约束而不是靠使用者自觉:

  1. EADDRINUSE 不等于该杀,先判断该不该杀,复用优先于重启。
  2. 绝不 killall node / pkill -f node,只做精确 PID kill,不误伤其他正常服务。
  3. PID < 100 绝不杀,那是系统进程。
  4. 别人的进程不杀,换端口绕开。
  5. 命令行看不懂、不确定是什么时,停下报告用户,不擅自杀。

安装与启用

两种安装方式。README 注明,第一种要等插件发布到 npm 之后才可用:

# 发布到 npm 后
dsh plugin --profile demo add dsh-port-guard

# 或从 GitHub 安装
dsh plugin --profile demo add github:PangYiMing/dsh-port-guard

两条命令都会把 dsh-port-guard 装进 --profile 指定的 profile。

典型用法

按一次真实的端口冲突走一遍:

1、先定位取证:

./scripts/port-guard.sh 8080

2、看输出判读。如果是自己项目上次遗留的 dev server,先确认它还活着,活着就直接复用,不必重启:

kill -0 "$PID" && echo alive

3、如果占端口的是别人的项目或系统服务,换端口绕开,不动别人的进程:

PORT=18080 node index.js

4、只有确认是僵尸或残留进程,才走精确 kill:

./scripts/port-guard.sh 8080 --kill

适用场景与注意

适合经常在本机启动 dev server 的智能体工作流和开发者,尤其是机器上同时跑着多个项目、不希望一次端口冲突演变成误杀的场景。

两点注意:

  • 插件以当前 dsh 进程的权限运行,kill 模式操作的是真实进程。安装前应检查源码与许可证(本插件为 MIT)。
  • 判读规则是参考,不是免检:遇到 tty=ttys00X 这类「有人在终端里跑」的进程,杀之前先向用户确认。

小结

dsh-port-guard 的价值不在 kill 本身,而在 kill 之前的判读:EADDRINUSE 有三条路,无脑 kill 只是其中最差的一条。把定位、取证、判读、处置固化成脚本和安全红线,端口冲突的处理就不再靠碰运气。

  • 社区目录页:https://www.skillhub.cn/plugins/PangYiMing/dsh-port-guard (第三方社区目录,非官方应用商店)
  • GitHub 仓库:https://github.com/PangYiMing/dsh-port-guard
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜