witr:基于 Go 的系统进程分析工具项目

Why is this running? Trace any process, port, container, or file back to what started it - CLI + TUI.

Branch2Tags21
This repository is empty

witr

这东西为什么在运行?

追踪任何进程、端口、容器或文件的完整启动链路 —
一条命令、机器可读的 JSON,或一个 交互式 TUI 即可搞定。

Latest Release Platforms
Package Managers

pranshuparmar/witr on Trendshift witr - Why is this running? Trace process, port, container or file. | Product Hunt

🎮 在浏览器中试用 witr →

探索模拟的 Linux 环境 — 包含引导教程和自由操作沙箱,无需安装。

witr 的交互式 TUI 和 CLI 展示 node 进程的运行原因 — 两种模式下均显示 systemd → PM2 → node 的完整链路



1. 用途

witr 的存在只为回答一个问题:

这东西为什么在运行?

当系统上有进程、服务或端口绑定的程序在运行时,其背后必然存在原因。这些原因往往是间接的、不明显的,或者分布在多个层级,例如进程管理器、容器、服务或 shell 中。

现有的工具(如 pstoplsofsssystemctldocker ps)会展示状态和元数据。它们能显示 正在运行什么,但需要用户手动关联不同工具的输出,自行推断 为什么运行

witr 让这种因果关系变得清晰可见。

它通过单一的、人类可读的输出或 交互式 TUI 仪表板,解释清楚 运行中的程序来自何处如何启动的 以及 当前负责维持其运行的一系列系统是什么

📖 想知道 witr 的由来?阅读故事 或浏览 Hacker News 讨论


2. 安装

witr 以单个静态二进制文件的形式发布,支持 Linux、macOS、FreeBSD 和 Windows 系统。

witr 也在多个操作系统和生态系统中由独立开发者打包和维护。最新的打包状态 overview 可在 Repology 上查看。请注意,社区软件包的版本可能因独立审核和验证流程而落后于 GitHub 上的发布版本。

Tip

如果您使用包管理器(如 Homebrew、Conda、Winget 等),建议通过包管理器安装,以便于后续更新。否则,安装脚本是快速开始使用的最佳方式。


2.1 快速安装

Unix(Linux、macOS 和 FreeBSD)

curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash
脚本详情

此脚本将:

  • 检测您的操作系统(linuxdarwinfreebsd
  • 检测您的 CPU 架构(amd64arm64
  • 下载最新发布的二进制文件和手册页
  • 将其安装到 /usr/local/bin/witr
  • 将手册页安装到 /usr/local/share/man/man1/witr.1
  • 可通过传递 INSTALL_PREFIX 来覆盖默认安装路径

Windows (PowerShell)

irm https://raw.githubusercontent.com/pranshuparmar/witr/main/install.ps1 | iex
脚本详情

该脚本将:

  • 下载最新版本(zip压缩包)并验证校验和。
  • witr.exe 提取到 %LocalAppData%\witr\bin
  • 将 bin 目录添加到用户 PATH 环境变量中。

2.2 包管理器

APT(Debian、Ubuntu 及衍生系统) Debian

您可以从 Debian 和 Ubuntu 的官方仓库(Ubuntu 26.04 及以上版本、Debian sid 及更高版本)以及 Kali Linux、Devuan、Raspbian 等衍生发行版中安装 witr

sudo apt install witr

注意:apt 提供的版本可能落后于最新的 GitHub 发布版本。如需使用最新功能,请使用安装脚本或其他安装方法。

Homebrew(macOS 和 Linux) Homebrew

你可以在 macOS 或 Linux 上使用 Homebrew 安装 witr

brew install witr
MacPorts (macOS) MacPorts

在 macOS 上,您可以使用 MacPorts 安装 witr

sudo port install witr
Conda(macOS、Linux 和 Windows) Conda

你可以在 macOS、Linux 和 Windows 上使用 condamambapixi 安装 witr

conda install -c conda-forge witr
# alternatively using mamba
mamba install -c conda-forge witr
# alternatively using pixi
pixi global install witr
Arch Linux (AUR) AUR

在 Arch Linux 及其衍生系统上,可通过 AUR 包 进行安装:

yay -S witr-bin
# alternatively using paru
paru -S witr-bin
# or use your preferred AUR helper
Winget (Windows) Winget

您可以通过 winget 安装 witr

winget install -e --id PranshuParmar.witr
NPM(跨平台) NPM

您可以使用 npm 安装 witr

npm install -g @pranshuparmar/witr
FreeBSD 端口 FreeBSD Port

您可以通过 FreshPorts 端口 在 FreeBSD 上安装 witr

pkg install witr
# or
pkg install sysutils/witr

或者从 Ports 构建:

cd /usr/ports/sysutils/witr/
make install clean
Chocolatey(Windows) Chocolatey

您可以使用 Chocolatey 安装 witr

choco install witr
Scoop(Windows) Scoop

您可以使用 Scoop 安装 witr

scoop install main/witr
AOSC OS AOSC OS

你可以从 AOSC OS 软件仓库 安装 witr

oma install witr
GNU Guix GNU Guix

你可以从 GNU Guix 软件仓库 安装 witr

guix install witr
Uniget(Linux) Uniget

您可以使用 uniget 安装 witr

uniget install witr
Aqua(macOS、Linux 和 Windows) Aqua

您可以使用 aqua 安装 witr

# Add package
aqua g -i pranshuparmar/witr

# Install package
aqua i pranshuparmar/witr
Brioche(Linux) Brioche

您可以使用 brioche 安装 witr

brioche install -r witr
Mise(macOS、Linux 和 Windows) Mise

您可以使用 mise 安装 witr

mise use github:pranshuparmar/witr
预构建包(deb、rpm、apk)

witr 为主流 Linux 发行版提供原生软件包。您可以从 GitHub 发布页面 下载最新的 .deb.rpm.apk 包。

  • 使用 curl 的通用下载命令:

    # 将 <package name> 替换为您需要的实际包名
    curl -LO https://github.com/pranshuparmar/witr/releases/latest/download/<package-name>
    
  • Debian/Ubuntu(.deb):

    sudo dpkg -i ./witr-*.deb
    # 或者,使用 apt 进行依赖项解析:
    sudo apt install ./witr-*.deb
    
  • Fedora/RHEL/CentOS(.rpm):

    sudo rpm -i ./witr-*.rpm
    
  • Alpine Linux(.apk):

    sudo apk add --allow-untrusted ./witr-*.apk
    

2.3 源码与手动安装

Go(跨平台)

您可以直接从源码安装最新版本:

go install github.com/pranshuparmar/witr/cmd/witr@latest

这会将 witr 二进制文件放置在您的 $GOPATH/bin$HOME/go/bin 目录中。请确保此目录已添加到您的 PATH 环境变量中。

手动安装

如果您倾向于手动安装,请按照以下适用于您平台的简单步骤操作:

类 Unix 系统(Linux、macOS、FreeBSD)

# 1. Determine OS and Architecture
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
[ "$ARCH" = "x86_64" ] && ARCH="amd64"
[ "$ARCH" = "aarch64" ] && ARCH="arm64"

# 2. Download the binary
curl -fsSL "https://github.com/pranshuparmar/witr/releases/latest/download/witr-${OS}-${ARCH}" -o witr

# 3. Verify checksum (Optional)
curl -fsSL "https://github.com/pranshuparmar/witr/releases/latest/download/SHA256SUMS" -o SHA256SUMS
grep "witr-${OS}-${ARCH}" SHA256SUMS | (sha256sum -c - 2>/dev/null || shasum -a 256 -c - 2>/dev/null)
rm SHA256SUMS

# 4. Rename and install
chmod +x witr
sudo mkdir -p /usr/local/bin
sudo mv witr /usr/local/bin/witr

# 5. Install man page (Optional)
sudo mkdir -p /usr/local/share/man/man1
sudo curl -fsSL https://github.com/pranshuparmar/witr/releases/latest/download/witr.1 -o /usr/local/share/man/man1/witr.1

Windows(PowerShell)

# 1. Determine Architecture
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") {
    $ZipName = "witr-windows-amd64.zip"
} elseif ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") {
    $ZipName = "witr-windows-arm64.zip"
} else {
    Write-Error "Unsupported architecture: $($env:PROCESSOR_ARCHITECTURE)"
    exit 1
}

# 2. Download the zip
Invoke-WebRequest -Uri "https://github.com/pranshuparmar/witr/releases/latest/download/$ZipName" -OutFile "witr.zip"
# 3. Extract the binary
Expand-Archive -Path "witr.zip" -DestinationPath "." -Force

# 4. Verify checksum (Optional)
Invoke-WebRequest -Uri "https://github.com/pranshuparmar/witr/releases/latest/download/SHA256SUMS" -OutFile "SHA256SUMS"
$hash = Get-FileHash -Algorithm SHA256 .\witr.zip
$expected = Select-String -Path .\SHA256SUMS -Pattern $ZipName
if ($expected -and $hash.Hash.ToLower() -eq $expected.Line.Split(' ')[0]) { Write-Host "Checksum OK" } else { Write-Host "Checksum Mismatch" }

# 5. Install to local bin directory
$InstallDir = "$env:LocalAppData\witr\bin"
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
Move-Item .\witr.exe $InstallDir\witr.exe -Force

# 6. Add to User Path (Persistent)
$UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($UserPath -notlike "*$InstallDir*") {
    [Environment]::SetEnvironmentVariable("Path", "$UserPath;$InstallDir", "User")
    $env:Path += ";$InstallDir"
    Write-Host "Added to Path. You may need to restart PowerShell."
}

# 7. Cleanup
Remove-Item witr.zip
Remove-Item SHA256SUMS

2.4 无需安装即可运行

Nix Flake

如果您使用 Nix,可以从源代码构建 witr 并无需安装即可运行:

nix run github:pranshuparmar/witr -- --help
Pixi

如果您使用 pixi,则无需安装即可在 Linux 或 macOS 上运行:

pixi exec witr --help

2.5 其他操作

验证安装
witr --version
man witr
Shell 补全

witr 支持所有标志的 Tab 补全功能。若要启用此功能,请将以下相应行添加到您的 Shell 配置中:

Bash

echo 'eval "$(witr completion bash)"' >> ~/.bashrc
source ~/.bashrc

Zsh

echo 'eval "$(witr completion zsh)"' >> ~/.zshrc
source ~/.zshrc

Fish

witr completion fish | source
# To make it permanent:
witr completion fish > ~/.config/fish/completions/witr.fish

PowerShell

witr completion powershell | Out-String | Invoke-Expression
# To make it permanent, add the above line to your $PROFILE
卸载

如果您是通过包管理器(Homebrew、Conda 等)安装的,请使用相应的卸载命令(例如:brew uninstall witr)。

要完全移除通过脚本/手动方式安装的 witr

类 Unix 系统(Linux、macOS、FreeBSD)

sudo rm -f /usr/local/bin/witr
sudo rm -f /usr/local/share/man/man1/witr.1

Windows

Remove-Item -Recurse -Force "$env:LocalAppData\witr"

3. 交互模式(TUI)

不带任何参数运行 witr 或使用 -i 标志将启动交互模式(TUI)。这提供了一个实时的、基于终端的仪表板,包含四个选项卡,用于浏览进程、端口、容器和文件锁。

主要功能:

  • 进程选项卡:实时、可排序、可筛选的所有正在运行的进程列表,侧边面板显示高亮进程的祖先树。
  • 端口选项卡:开放/监听端口,侧边面板附带所属进程。按 a 可在仅 LISTEN 和全部之间切换。
  • 容器选项卡:在一个列表中显示 Docker、Podman、nerdctl、K8s/crictl、Incus、LXC、LXD 和 FreeBSD jails 上所有正在运行的容器 - 包括名称、镜像、状态、端口、命令,以及每个容器的详细视图,包含挂载、网络和 Compose 项目元数据。
  • 锁选项卡:系统级文件锁(Linux 上为 POSIX/FLOCK,macOS/FreeBSD 上为 lsof 衍生)。按 a 切换到“所有打开文件”模式,其中锁定条目与每个有趣的打开文件描述符合并;在 / 处输入可在合并集中搜索。
  • 进程详情:深入查看进程,以查看其完整的祖先树、子进程、环境变量、工作目录、套接字、文件上下文等。
  • 进程操作:直接从 UI 发送信号(Kill、Terminate、Pause、Resume)或调整进程优先级(仅 Unix)。
  • 鼠标支持:使用鼠标导航、排序列、点击行。
  • 自适应主题:颜色会自动适应终端的亮色和暗色背景。
  • 自动刷新:进程、端口、容器和锁列表按自适应节奏自动刷新(起始为 3 秒,负载下会延长)。

4. 标志与选项

  -c, --container strings container(s) to look up (repeatable)
      --env              show environment variables for the process
  -x, --exact            use exact name matching (no substring search)
  -f, --file strings     file(s) held open by a process (repeatable)
  -h, --help             help for witr
  -i, --interactive      interactive mode (TUI)
      --json             show result as JSON
      --no-color         disable colorized output
  -p, --pid strings      pid(s) to look up (repeatable)
  -o, --port strings     port(s) to look up (repeatable)
  -s, --short            show only ancestry
  -t, --tree             show only ancestry as a tree
      --verbose          show extended process information
  -v, --version          version for witr
      --warnings         show only warnings

位置参数(不带标志)被视为进程或服务名称。可以传入多个名称。默认情况下,名称匹配使用子字符串匹配(模糊搜索)。使用 --exact 可仅匹配名称完全一致的进程。

所有目标标志(--pid--port--file--container)均可重复使用,并且可以相互混合使用,也可以与位置名称参数混合使用。当提供多个目标时,结果会按顺序显示,并带有标签分隔符。所有输出模式(标准、简短、树状、JSON、环境变量、警告、详细)均支持多个输入。

--container 标志会跨 Docker、Podman、nerdctl、K8s/crictl、Incus、LXC、LXD 和 FreeBSD jails 进行搜索,并匹配容器名称、镜像、命令以及 Compose 项目/服务标签。

如果未提供参数或相关标志(--pid--port--file--container),或者显式使用 --interactive 标志,则会启动 TUI。


5. 核心概念

witr 将一切都视为进程问题

端口、服务、容器和命令最终都映射到PID。一旦确定了 PID,witr 就会构建一个因果链,解释该 PID 存在的原因。

witr 的核心功能是回答:

  1. 正在运行什么?
  2. 它是如何启动的?
  3. 是什么让它保持运行?
  4. 它属于什么上下文?

6. 示例输出

💡 更喜欢通过实践学习?交互式浏览器教程 会在模拟环境中实时引导你查看此类输出 — 无需安装即可更好地感受 witr。

6.1 基于名称的查询

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)

6.2 简洁输出

witr --port 5000 --short
systemd (pid 1) → PM2 v5.3.1: God (pid 1481580) → python (pid 1482060)

6.3 树形输出

witr --pid 143895 --tree
systemd (pid 1)
  └─ init-systemd(Ub (pid 2)
    └─ SessionLeader (pid 143858)
      └─ Relay(143860) (pid 143859)
        └─ bash (pid 143860)
          └─ sh (pid 143886)
            └─ node (pid 143895)
              ├─ node (pid 143930)
              ├─ node (pid 144189)
              └─ node (pid 144234)

注意:树形视图包含子进程(最多 10 个)并突出显示目标进程。


6.4 多个匹配项

witr ng
Multiple matching processes found:

[1] nginx (pid 2311)
    nginx -g daemon off;
[2] nginx (pid 24891)
    nginx -g daemon off;
[3] ngrok (pid 14233)
    ngrok http 5000

Re-run with:
  witr --pid <pid>

为避免子字符串匹配,仅查找名称完全匹配的进程,请使用 --exact 标志:

witr nginx -x

6.5 基于文件的查询

witr --file /var/lib/dpkg/lock

解释占用文件的进程。


6.6 基于容器的查询

witr --container redis

通过名称、镜像、命令或 Compose 项目/服务,在所有检测到的运行时(Docker、Podman、nerdctl、K8s/crictl、Incus、LXC、LXD、FreeBSD jails)中查找容器。传递 --verbose 可在输出中包含挂载、网络和 Compose 元数据。


6.7 多个输入

witr nginx --port 5432 --pid 1234
----- [name: nginx] -----
Target      : nginx
Process     : nginx (pid 2311)
...

----- [port: 5432] -----
Target      : postgres
Process     : postgres (pid 891)
...

----- [pid: 1234] -----
Target      : node
Process     : node (pid 1234)
...

所有目标标志均可重复使用,且可以混合搭配。结果将按照您输入的顺序显示。所有输出模式(--short--tree--json--env--warnings--verbose)均支持多个输入。


7. 输出行为

7.1 输出原则

  • 默认情况下显示单屏内容(尽最大努力)
  • 确定性排序
  • 叙述式解释
  • 尽最大努力检测,并明确标注不确定性

7.2 退出代码

witr 返回有意义的退出代码,可用于脚本、CI 管道和监控:

代码 含义
0 正常:找到进程,无警告
1 警告:找到进程,但存在一个或多个警告
2 未找到:没有匹配的进程或服务
3 权限被拒绝:权限不足
4 无效输入:参数错误或匹配不明确
5 内部错误:发生意外故障

示例用法:

witr nginx --short
case $? in
  0) echo "All clear" ;;
  1) echo "Warnings detected" ;;
  2) echo "Process not running" ;;
  3) echo "Need elevated privileges" ;;
  4) echo "Invalid input or ambiguous match" ;;
  5) echo "Internal error" ;;
esac

7.3 标准输出部分

目标

用户所查询的对象。

进程

可执行文件、PID、用户、命令、启动时间以及重启次数。

存在原因

展示进程产生过程的因果溯源链。 这是 witr 的核心价值。

来源

负责启动或监管该进程的主要系统(尽最大努力识别)。

示例:

  • 带有定时器触发服务调度信息的 systemd 单元(Linux)
  • 包含调度/触发详情的 launchd 服务(macOS)
  • SSH 会话(含远程 IP 和终端)
  • docker 容器
  • pm2
  • cron
  • 交互式 shell(可检测 tmux/screen 会话)
  • Snap/Flatpak 沙箱(Linux)

仅选择一个主要来源

上下文(尽最大努力)

  • 工作目录
  • Git 仓库名称及分支
  • 容器名称/镜像(docker、podman、kubernetes、colima、containerd)
  • 公共与私有绑定

警告

非阻塞性观察结果,例如:

  • 进程以 root 用户身份运行
  • 非 root 进程拥有危险的 Linux capabilities(如 CAP_SYS_ADMIN 等)
  • 进程监听公共接口(0.0.0.0 / ::)
  • 多次重启(仅在超过阈值时发出警告)
  • 进程使用高内存(RSS >1GB)
  • 进程已运行超过 90 天
  • 已删除的二进制文件、库注入迹象(LD_PRELOAD、DYLD_*)

8. 平台支持

  • Linux(x86_64、arm64)- 完整功能支持(基于 /proc)。
  • macOS(x86_64、arm64)- 使用 pslsofsysctlpgrep
  • Windows(x86_64、arm64)- 原生 Win32 API(ToolHelp32、PSAPI、服务控制管理器)。无 PowerShell 或 WMI 依赖。
  • FreeBSD(x86_64、arm64)- 使用 procstatpslsof

8.1 功能兼容性矩阵

功能 Linux macOS Windows FreeBSD 说明
进程选择
按名称
按 PID
按端口
按文件
按容器 需要运行时 CLI 在 PATH 中(docker/podman/nerdctl/crictl/incus/lxc/lxc-ls/jls)。
多个/混合输入 可重复的标志,混合类型。
精确匹配
完整命令行
进程启动时间
工作目录
环境变量 ⚠️ ⚠️ macOS:受 SIP 限制;Windows:受保护进程无法访问。
网络
监听端口
绑定地址
端口 → PID 解析
端口 → 容器回退 当端口由 PID 1 通过 systemd 套接字激活或容器运行时拥有时使用。
服务检测
服务管理器 Linux:systemd,macOS:launchd,Windows:服务,FreeBSD:rc.d
服务描述 Linux:Description,macOS:Comment,Windows:Display Name,FreeBSD:rc
配置来源 Linux:单元文件,macOS:Plist,Windows:注册表项,FreeBSD:Rc 脚本
监管程序
容器 Docker(含 compose 映射)、Podman、nerdctl、K8s(Kubepods/crictl)、Containerd。macOS/Linux 上的 Colima。Linux 上的 Incus/LXC/LXD。FreeBSD 上的 Jails。
SSH 会话检测 检测远程 IP 和终端。
tmux/screen 检测 在来源中显示会话名称。
调度检测 Linux:systemd 定时器,macOS:launchd 间隔/日历。
Snap/Flatpak 检测
健康与诊断
CPU 使用率检测
内存使用率检测
健康状态检测
打开的文件/句柄 ⚠️ Windows:仅计数。
文件锁 Linux:/proc/locks;macOS/FreeBSD:从 lsof/fstat 推导。
已删除二进制文件检测 若可执行文件缺失则发出警告。
Capability 警告 对非 root 进程拥有的危险 capabilities 发出警告。
上下文
Git 仓库/分支检测
交互模式(TUI)
进程选项卡
端口选项卡
容器选项卡
锁选项卡 切换(a)显示所有打开的文件。
进程详情
进程操作

图例: ✅ 完全支持 | ⚠️ 部分/有限支持 | ❌ 不支持


8.2 权限说明

Linux/FreeBSD

witr 会检查系统目录,这可能需要提升权限。

如果未看到预期信息,请尝试使用 sudo 运行 witr:

sudo witr [your arguments]

macOS

在 macOS 上,witr 使用 pslsoflaunchctl 来收集进程信息。部分操作可能需要提升权限:

sudo witr [your arguments]

注意:由于 macOS 系统完整性保护(SIP),即使使用 sudo,某些系统进程的详细信息也可能无法访问。

Windows

在 Windows 上,witr 直接与 Win32 API(ToolHelp32、PSAPI、服务控制管理器)交互,而不是生成 PowerShell 或 WMI,因此启动速度很快,且不会出现 Get-CimInstance 挂起的情况。若要查看其他用户拥有的进程或系统服务的详细信息,必须以管理员身份运行终端。

# Run in Administrator PowerShell
.\witr.exe [your arguments]

9. 成功标准

witr 若满足以下条件,则视为成功:

  • 用户能在几秒钟内解答“为什么它在运行?”
  • 减少对多种工具的依赖
  • 在压力下输出内容仍易于理解
  • 用户在事件期间信任它

10. 赞助者

特别感谢支持 witr 的人们 ❤️