端口被谁占用、容器里跑的是什么:用 witr 回溯进程的启动链
ps、top 告诉你什么在跑,lsof、ss 告诉你是谁占着端口,systemctl、docker ps 告诉你服务状态。但这些都是状态:拿到几份输出,还得自己把信息串起来,才能回答"这东西为什么在跑"。
服务背后往往隔着好几层——supervisor、容器、shell、init——起因是间接的,也不在一个工具的视野里。witr 要回答的就是这一句:Why is this running? 它把进程、端口、容器、文件回溯到确切的启动链,输出可以是终端里的一行、机器可读的 JSON,或者交互式 TUI。
一切归到 PID
端口、服务、容器、文件,witr 都当作"进程问题"处理,最终映射到一个 PID。拿到 PID 之后,它构建一条解释"这个 PID 为什么存在"的因果链,回答四件事:在跑什么、怎么启动的、谁在维持它、它属于什么上下文。
安装
单个静态二进制,覆盖 Linux / macOS / FreeBSD / Windows。
curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash
irm https://raw.githubusercontent.com/pranshuparmar/witr/main/install.ps1 | iex
包管理器:apt install witr、brew install witr、conda install -c conda-forge witr、yay -S witr-bin、winget install -e --id PranshuParmar.witr、npm install -g @pranshuparmar/witr、FreeBSD 用 pkg install witr。
源码安装:
go install github.com/pranshuparmar/witr/cmd/witr@latest
TUI
直接运行 witr,或者 witr -i。四个 Tab:
- Processes:进程列表,侧栏给出祖先树
- Ports:监听端口和所属进程,按
a在 LISTEN / ALL 之间切换 - Containers:Docker、Podman、nerdctl、crictl、Incus、LXC、LXD、FreeBSD jail 统一列出
- Locks:系统级文件锁,按
a切换到所有打开文件
支持鼠标、跟随终端自适应主题、自动刷新(从 3 秒起,负载高时退避),也能直接从 UI 里发信号(Kill / Terminate / Pause / Resume),或在 Unix 上 renice。
关键 flags
-c, --container 查容器
--env 显示环境变量
-x, --exact 精确匹配
-f, --file 按文件查
-h, --help
-i, --interactive
--json 输出 JSON
--no-color
-p, --pid
-o, --port
-s, --short 只显示祖先链
-t, --tree 树形祖先链
--verbose
-v, --version
--warnings
位置参数按进程名/服务名做子串(模糊)匹配。多个目标可以混用,结果按顺序分段输出。
输出长什么样
witr node:
Target : node
Process : node (pid 14233)
User : pm2
Command : node index.js
Started : 2 days ago (Mon 2025-02-02 11:42:10 +05:30)
Why It Exists :
systemd (pid 1) → pm2 (pid 5034) → node (pid 14233)
Source : pm2
Working Dir : /opt/apps/expense-manager
Git Repo : expense-manager (main)
Sockets : 127.0.0.1:5001 (TCP | LISTENING)
只想看链条,用 --short。比如 witr --port 5000 --short:
systemd (pid 1) → PM2 v5.3.1: God (pid 1481580) → python (pid 1482060)
要看完整的树,witr --pid 143895 --tree 会打印 systemd → … → node 的树,最多带上 10 个子进程,并高亮目标本身。
几个具体场景
端口被谁占着:witr -o 5000 直接给出端口对应的 PID 和它的启动来源,不用 ss 完再 lsof 再 ps -ef 一层层扒。
文件被谁占着:witr --file /var/lib/dpkg/lock 解释谁持有这个文件。macOS 上没有 /proc,这一块更多依赖 lsof 一类工具的信息来推导。
容器里跑的是什么:witr --container redis 跨运行时查找,加 --verbose 会输出 mounts / networks / compose metadata。
名字匹配到多个目标:witr ng 会同时列出 nginx、nginx、ngrok 之类的匹配项,提示你用 --pid 精确定位,或者加 -x 做精确匹配。
不装也能先看效果: 提供了模拟 Linux 机器的引导教程和自由沙箱。
项目地址: