最近我大量使用 Claude Code 进行 Vibe Coding,也做了不少自己的小项目和小工具。这些工具在运行时,往往会启动本地服务器来提供 Web 或 API 服务。本地调试确实很方便,但问题在于,用完之后它们并不总能被彻底关闭。
有时即使显式让它退出,进程也未必真的结束;有时直接关闭会话窗口,服务却依然在后台运行。久而久之,系统里就残留了不少 Web 服务进程,占用内存和端口。
这类残留进程会带来几个比较麻烦的问题:
1. AI 误判服务状态
在 AI Coding 场景下,AI 判断服务是否启动,通常只是简单扫描端口是否被占用。
如果某个端口早已被旧项目占用,AI 很可能误以为当前服务已经启动成功,但实际上目标进程根本没有运行。
结果就是:看起来一切正常,实际上什么都没跑起来。
2. 端口冲突导致反复修改配置
当端口被占用时,AI 需要重新启动服务。但很多项目的端口是写死在配置文件中的,于是它不得不读取文件、修改端口、再运行服务。
由于每次冲突的端口都不一样,几乎每次都要改一遍配置。
这种“改端口—重启—再改端口”的循环,非常影响节奏。
3. 自动关闭进程容易误杀
如果让 AI 去“清理端口占用”,问题就更复杂了。
它通常只是扫描占用端口的进程,然后直接终止。
但 AI 并不知道哪些进程是当前项目的,哪些是你正在运行的重要服务。
一刀切式地 kill 掉,很容易误伤无辜。
基于这些困扰,我干脆写了一个小工具,用来手动、快速清理这些遗留的端口进程。
它可以一键列出所有占用端口的进程,让我自行判断并清理。
既然是日常会频繁使用的小工具,那就干脆做成命令行工具,一键调用。
于是我用 Rust 写了一个 TUI(Terminal UI)程序。从开始到完成不到一天时间,就已经开发完成,并发布到了 GitHub 和 Cargo 上。
感兴趣的话可以试试:
👉 https://github.com/yeung66/ccpclean
可以通过 cargo install 安装,或者直接下载二进制文件运行。
核心逻辑
程序本身的逻辑非常简单:
- 扫描当前系统进程
- 找出所有占用端口的进程
- 展示相关信息,包括:
- 执行命令
- 父进程信息
- 支持手动选择并终止进程
通过父进程和命令信息,基本可以判断该服务属于哪个项目。
此外,我加入了一些简单规则,用来判断该进程是否可能由 Claude Code 或其他 AI Agent 启动,并给出一个参考评分,用来辅助判断是否值得清理。
宽松模式
除了默认模式,还提供了一个“宽松模式”。
因为遗留服务不仅发生在 AI 场景中。
很多时候我们在命令行启动一个服务,关闭终端后它依然在后台运行。
宽松模式会列出所有占用端口的服务,方便逐个浏览、筛选和清理。
当然,这些事情完全可以通过原生命令行工具实现,比如:
lsofnetstatsskill
但当你需要频繁做这件事时,一个专门的小工具会更高效。
而且,用 Rust 写个 TUI 的体验本身也很不错。
在 AI 的加持下,从想法到可用版本几乎没有门槛。
既然能提效,又几乎不费劲,那为什么不用一个小工具呢?
























