问题:你的 CPU 到底在跑什么?
笔记本电脑风扇狂转,电池疯狂掉电,但你不知道 culprit 是谁。打开 Activity Monitor 或 Task Manager,只能看到一堆进程名,却无法回答最根本的问题:
“Why is this running?”
- 这个进程是谁启动的?
- 它为什么还在运行?
- 它占用了哪些端口?
- 它的子进程有哪些?
- 杀死它会不会影响其他东西?
传统工具(htop, top, ps)只能给你快照,无法给你血缘。
Witr 是什么?
Witr (“Why is this running?")是一个用 Go 编写的开源进程分析工具。它在 GitHub 上拥有 15,042+ Stars,回答了每个系统管理员和开发者心中的终极问题。
Witr 的核心能力:展示进程的完整因果链 —— 从 init 系统到你的目标进程,完整展示"谁生了谁"的家族树。
核心功能
1. 进程血缘树(Process Ancestry)
Witr 的杀手锏功能。运行 witr <PID>,你会看到:
init(1)
└── systemd(1234)
└── dockerd(5678)
└── containerd-shim(9012)
└── node(3456) ← Your App
├── npm(7890)
└── webpack-dev-server(2345)
一目了然:这个 Node.js 进程是 Docker 容器里的,由 systemd 启动,webpack-dev-server 是它的子进程。
2. 交互式 TUI 模式
Witr 不只是命令行输出,它有一个完整的终端用户界面:
| 功能 | 快捷键 | 说明 |
|---|---|---|
| 实时进程列表 | ↑↓ | 所有运行中进程,支持排序过滤 |
| 端口视图 | p | 查看端口占用及对应进程 |
| 进程详情 | Enter | 完整血缘树、子进程、环境变量、工作目录 |
| 发送信号 | k | Kill、Terminate、Pause、Resume |
| 调整优先级 | r | Renice 进程 |
| 鼠标支持 | 🖱️ | 点击排序、选择行 |
3. 端口视图
$ witr --ports
PORT PROTO PROCESS PID USER
8080 TCP node 3456 ubuntu
3000 TCP webpack-dev 2345 ubuntu
5432 TCP postgres 5678 postgres
22 TCP sshd 1234 root
一眼看清谁在监听什么端口,再也不用 lsof -i :8080 了。
4. 环境变量与工作目录
$ witr 3456 --env
PID: 3456
Command: node server.js
Working Directory: /home/ubuntu/myapp
Environment Variables:
NODE_ENV=production
PORT=8080
DATABASE_URL=postgresql://...
API_KEY=sk-***
调试配置问题的神器 —— 直接看进程实际运行的环境。
5. 信号发送
从 TUI 直接发送信号:
SIGKILL(9) —— 强制终止SIGTERM(15) —— 优雅终止SIGSTOP(19) —— 暂停SIGCONT(18) —— 恢复
不用记 kill -9 PID,按 k 选就行。
安装
一键安装
# macOS / Linux
curl -fsSL https://github.com/pranshuparmar/witr/releases/latest/download/witr-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') -o witr
chmod +x witr
sudo mv witr /usr/local/bin/
# Go 安装
go install github.com/pranshuparmar/witr/cmd/witr@latest
支持平台
- ✅ Linux
- ✅ macOS
- ✅ Windows
- ✅ FreeBSD
使用示例
基本用法
# 启动交互式 TUI
witr
# 查看特定进程的血缘树
witr 3456
# 查看端口占用
witr --ports
# 查看进程环境变量
witr 3456 --env
# 持续监控模式
witr --watch
实际场景
场景 1:找出耗电元凶
$ witr
# 按 CPU 排序,发现 node 进程占 80%
# Enter 查看详情:是 webpack-dev-server
# k → SIGTERM → 优雅关闭
场景 2:端口冲突
$ witr --ports
# 发现 8080 被占用
# 查看进程:是昨天遗留的测试服务器
# k → SIGKILL → 释放端口
场景 3:调试容器
$ witr $(docker inspect -f '{{.State.Pid}}' mycontainer)
# 查看容器内进程的血缘树
# 环境变量、工作目录一目了然
与同类工具对比
| 功能 | Witr | htop | ps | lsof |
|---|---|---|---|---|
| 进程血缘树 | ✅ 完整 | ❌ 无 | ❌ 无 | ❌ 无 |
| 交互式 TUI | ✅ 是 | ✅ 是 | ❌ 否 | ❌ 否 |
| 端口视图 | ✅ 内置 | ❌ 无 | ❌ 无 | ✅ 是 |
| 环境变量 | ✅ 一键 | ❌ 无 | ⚠️ 复杂 | ❌ 无 |
| 信号发送 | ✅ 交互 | ⚠️ 有限 | ❌ 无 | ❌ 无 |
| 鼠标支持 | ✅ 是 | ✅ 是 | ❌ 否 | ❌ 否 |
| 跨平台 | ✅ 4 平台 | ✅ 多平台 | ✅ 通用 | ✅ 多平台 |
架构
Witr 用 Go 编写,利用操作系统原生 API:
- Linux:
/proc文件系统 - macOS:
libproc+sysctl - Windows: Windows API
- FreeBSD:
kvm+sysctl
纯 Go 实现,无 CGO 依赖(Windows 除外),单二进制文件,零依赖。
结论
Witr 不是 htop 的替代品,而是进程调试的专用工具。当你需要回答"Why is this running?“时,Witr 比任何工具都快。
- 15K+ Stars 证明它解决了真实痛点
- 单二进制文件,随处可用
- TUI 体验流畅,鼠标键盘都支持
GitHub: pranshuparmar/witr
Stars: 15,042+ | Language: Go | License: Open Source

有问题或想法?欢迎在下方留下你的评论。使用 GitHub 账号登录即可参与讨论。