前言¶
本地起 dev server,最常碰到的第一个障碍就是 EADDRINUSE: address already in use。在智能体工作流里,这个报错往往出现在任务最开头,而常见的处理方式很粗:直接 killall node 或 pkill -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/null且fd1/fd2 → 某个 .log:nohup 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
安全红线¶
插件内置了五条红线,是设计约束而不是靠使用者自觉:
- EADDRINUSE 不等于该杀,先判断该不该杀,复用优先于重启。
- 绝不
killall node/pkill -f node,只做精确 PID kill,不误伤其他正常服务。 - PID < 100 绝不杀,那是系统进程。
- 别人的进程不杀,换端口绕开。
- 命令行看不懂、不确定是什么时,停下报告用户,不擅自杀。
安装与启用¶
两种安装方式。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