witr 使用指南:从“什么在运行”到“为什么在运行”

一、介绍

witr 是一个用 Go 编写的系统诊断工具,名称来自它要回答的核心问题:“Why is this running?”(这为什么在运行?)。

传统的 ps、top、lsof、ss 告诉你的是一堆“事实”——哪个进程在跑、哪个端口被占。witr 做的事不一样:它把这些事实串成一条因果链。你给它一个 PID、端口或容器名,它往上追溯:是谁启动了它?是 systemd 服务、Docker Compose、npm dev server,还是某个 SSH 会话?

它的定位是“在经典可观测性命令之上的一层因果解释”,尤其适合开发者在本地机器、容器、服务管理器和语言特定的开发服务器之间来回切换时使用。

github地址:https://github.com/pranshuparmar/witr

二、安装

witr 的安装方式覆盖了几乎所有主流平台和包管理器。以下按平台分类。

Windows

# Winget(推荐)
winget install -e --id PranshuParmar.witr

# Scoop
scoop install main/witr

# Chocolatey
choco install witr

# 一行式 PowerShell 脚本
irm https://raw.githubusercontent.com/pranshuparmar/witr/main/install.ps1 | iex

Windows 版本使用 Get-CimInstance、tasklist、netstat 收集信息,不需要 WSL 或 PowerShell 兼容层。

macOS / Linux

# Homebrew(macOS 和 Linux)
brew install witr

# 通用一行式脚本
curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash

# Conda(跨平台)
conda install -c conda-forge witr

# Arch Linux (AUR)
yay -S witr-bin

# Go 直接安装
go install github.com/pranshuparmar/witr/cmd/witr@latest

此外还提供 .deb / .rpm / .apk 原生包,以及 Nix、npm、FreeBSD Ports、GNU Guix 等多种渠道。

安装后验证:witr --version,查看手册:man witr。

三、核心使用场景与命令

3.1 按端口排查:谁占了我的 8080?

witr --port 8080
# 或简写
witr -p 8080

输出不仅告诉你 PID,还会显示因果链——比如 node → npm → zsh → terminal,让你一眼看到这个开发服务器是怎么被拉起来的。

3.2 按 PID 或进程名追溯来源

# 按 PID
witr 1234

# 按名称(默认子串模糊匹配)
witr nginx

# 精确匹配
witr nginx --exact
# 或
witr nginx -x

如果输入的名称匹配到多个进程,witr 会列出所有候选项并要求你指定具体 PID,避免误判。

3.3 组合查询:一条命令回答多个问题

witr 的目标参数可以混合、重复使用,结果按输入顺序依次输出,用带标签的分隔线划分区块:

witr nginx --port 5432 --pid 1234

输出会分成三个清晰的区块:

----- [name: nginx] -----
----- [port: 5432] -----
----- [pid: 1234] -----

这让“同时查多个不相关的对象”变成一条命令的事。

3.4 交互式 TUI 仪表盘

witr --interactive
# 或
witr -i

启动一个终端仪表盘,分标签页展示进程、端口、容器和文件锁。快捷键包括:

按键功能
↑ / ↓导航进程列表
Enter展开因果链详情
f过滤/搜索
r刷新
q / Ctrl+C退出

四、进阶用法

4.1 JSON 输出:接入自动化

witr --json 1234
witr --json --port 8080

适合脚本解析,例如在 Shell 脚本里判断端口归属:

if witr --json --port 8080 > /tmp/w.json 2>/dev/null; then
  SERVICE=$(jq -r '.causality_chain[-1].service // "unknown"' /tmp/w.json)
  echo "8080 归属:$SERVICE"
fi

4.2 监视模式

witr --watch 1234

持续刷新,观察进程状态变化,适合调试启动过程中的竞态问题。

4.3 按用户过滤

witr --all --user www-data

查看特定用户拥有的所有进程及其来源。

五、平台支持与限制

witr 在四大平台上都有支持,但功能完整度有差异:

功能LinuxmacOSWindowsFreeBSD
按端口查询✅✅✅✅
服务管理器检测systemdlaunchdWindows Servicesrc.d
容器检测✅✅✅✅
环境变量✅⚠️ 部分❌✅
按文件查询✅✅❌✅
计划任务检测✅✅❌❌

Windows 上不支持的功能:按文件句柄查询、环境变量查看、tmux/screen 检测、计划任务检测。容器和 Git 仓库检测是支持的。

六、优化与技巧

6.1 权限问题

在 Linux/FreeBSD 上,witr 需要读取 /proc 等系统目录。如果看不到预期信息,加 sudo:

sudo witr --port 80

macOS 上部分操作也可能需要提升权限。

6.2 与现有工具链配合

witr 不是要替代 ps、lsof,而是补充它们。典型工作流是:用 ss 或 netstat 发现异常端口 → 用 witr --port 追溯来源 → 用 witr --watch 观察后续变化。

6.3 容器场景

witr 能识别 Docker、Podman、K8s(Kubepods)、Containerd,以及 macOS/Linux 上的 Colima。对 Docker Compose 项目,它会显示 Compose 映射信息。

witr <容器内进程的PID>
# 输出会显示:container → container runtime → systemd 链

6.4 在脚本中使用

由于 --json 输出结构稳定,witr 很适合嵌入运维脚本。结合 jq 可以提取因果链中的服务名、父进程等信息,用于自动化告警或审计。

6.5 多目标查询的输出定位

当一条命令查询多个目标时,输出按输入顺序排列,每个区块前有 ----- [name: ...] ----- 或 ----- [port: ...] ----- 分隔线。标签写的是你查询的原始目标,不是解析后的进程名——比如 [port: 5432] 区块里实际显示的进程可能是 postgres。

七、总结

witr 用一条命令替代了“先 ss 看端口,再 ps 找 PID,再 pstree 看父进程”的手工串联流程。

如果你经常在本地同时跑多个服务、容器和开发服务器,它会显著缩短“这东西到底是哪来的”这个问题的排查时间。