witr 技术指南:一键追溯进程、端口、容器与文件的完整启动因果链(CLI + TUI)
【免费下载链接】witrWhy is this running? Trace any process, port, container, or file back to what started it - CLI + TUI.项目地址: https://gitcode.com/GitHub_Trending/wi/witr
witr(Why is this running?)是一个用于 Linux、macOS、Windows 与 FreeBSD 的进程因果溯源工具:它能把任意进程、端口、容器或文件锁定,一路追溯到“到底是谁启动了它”,并以单条人类可读输出、机器可读 JSON 或交互式 TUI 仪表盘三种形态呈现。本文以仓库根目录 README.md 为主线,结合 internal/app/app.go、internal/pipeline/analyze.go、internal/proc/ancestry.go、internal/source/detect.go 等源码实现,完整讲解 witr 的安装方式、全部命令行参数、核心工作原理、输出格式、退出码与跨平台能力矩阵,读完即可在真实环境中用它排查“这台机器上到底为什么跑着这个东西”。
1. 设计动机:从“什么是运行的”到“为什么在运行”
witr 的存在是为了回答一个单一问题:
Why is this running?(为什么它在运行?)
系统上任何正在运行的东西——进程、服务、绑定到端口的监听者——都必然有一个原因。而这个原因往往是间接的、不直观的,并且分散在多个层面:supervisor(如 systemd、PM2)、容器、服务管理器、SSH 会话或交互式 Shell 等。
传统的排查工具(ps、top、lsof、ss、systemctl、docker ps)暴露的是状态与元数据:它们告诉你什么在运行,却把“为什么”留给你自己去跨工具人工比对。witr 把这种因果性显式化——它在一份输出中解释一件事从哪里来、如何被启动、当前由哪条系统链负责其存在。
从源码看,这个“追根溯源”的核心能力落在 internal/proc/ancestry.go 的ResolveAncestry:它从目标 PID 沿 PPID 指针逐级向上读取祖先进程,直到 PID 1 或 PPID 为 0,再做环保护(seen集合)与链表反转,最终得到从根到目标的完整进程链。整个分析管线则由 internal/pipeline/analyze.go 的AnalyzePID驱动:先取祖先链,再做来源检测(source.Detect),最后聚合出model.Result(含进程信息、祖先链、来源、警告、资源上下文等)。
2. 安装方式总览
witr 以单一静态二进制形式分发,支持 Linux、macOS、FreeBSD 与 Windows,同时被众多操作系统与生态独立打包维护。官方建议:若你使用包管理器(Homebrew、Conda、Winget 等),优先通过包管理器安装以便更新;否则使用安装脚本是上手最快的方式。需要说明的是,社区打包的版本可能因独立审核与验证流程而滞后于官方发布版本。
2.1 快速安装
Unix(Linux、macOS 与 FreeBSD)
curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash脚本行为(对应仓库根目录的 install.sh):
- 检测操作系统(
linux、darwin、freebsd); - 检测 CPU 架构(
amd64或arm64); - 下载最新发布的二进制与 man page;
- 安装到
/usr/local/bin/witr; - 安装 man page 到
/usr/local/share/man/man1/witr.1; - 可通过
INSTALL_PREFIX环境变量覆盖默认安装路径。
Windows(PowerShell)
irm https://raw.githubusercontent.com/pranshuparmar/witr/main/install.ps1 | iex脚本行为(对应 install.ps1):
- 下载最新发布包(zip)并校验 checksum;
- 解压
witr.exe到%LocalAppData%\witr\bin; - 将该 bin 目录加入用户的
PATH。
2.2 包管理器安装
witr 在主流包管理生态中均有打包,包括 APT、Homebrew、MacPorts、Conda、AUR、Winget、npm、FreeBSD Ports、Chocolatey、Scoop、AOSC OS、GNU Guix、Uniget、Aqua、Brioche 与 Mise。以下按生态列出安装命令:
| 生态 | 适用平台 | 命令 |
|---|---|---|
| APT(Debian/Ubuntu 及衍生版) | Linux | sudo apt install witr |
| Homebrew | macOS & Linux | brew install witr |
| MacPorts | macOS | sudo port install witr |
| Conda / mamba / pixi | macOS、Linux、Windows | conda install -c conda-forge witr、mamba install -c conda-forge witr、pixi global install witr |
| AUR(Arch Linux) | Linux | yay -S witr-bin或paru -S witr-bin |
| Winget | Windows | winget install -e --id PranshuParmar.witr |
| npm | 跨平台 | npm install -g @pranshuparmar/witr |
| FreeBSD Ports | FreeBSD | pkg install witr(或pkg install sysutils/witr);亦可cd /usr/ports/sysutils/witr/ && make install clean从 Ports 构建 |
| Chocolatey | Windows | choco install witr |
| Scoop | Windows | scoop install main/witr |
| AOSC OS | Linux | oma install witr |
| GNU Guix | Linux | guix install witr |
| Uniget | Linux | uniget install witr |
| Aqua | macOS、Linux、Windows | aqua g -i pranshuparmar/witr后aqua i pranshuparmar/witr |
| Brioche | Linux | brioche install -r witr |
| Mise | macOS、Linux、Windows | mise use github:pranshuparmar/witr |
此外,官方还提供deb / rpm / apk 预编译包,可从 GitHub Releases 页面下载:Debian/Ubuntu 用sudo dpkg -i ./witr-*.deb(或sudo apt install ./witr-*.deb让 apt 解析依赖),Fedora/RHEL/CentOS 用sudo rpm -i ./witr-*.rpm,Alpine 用sudo apk add --allow-untrusted ./witr-*.apk。
2.3 源码与手动安装
Go(跨平台,推荐开发者)
go install github.com/pranshuparmar/witr/cmd/witr@latest二进制会落到$GOPATH/bin或$HOME/go/bin,请确保该目录在PATH中。仓库根目录的 main.go 与 cmd/witr/main.go 即命令行入口:它调用app.SetVersion注入版本信息后执行app.Execute()。也可在构建时用-ldflags覆盖版本号、commit 与构建日期:
go build -ldflags "-X github.com/pranshuparmar/witr/internal/version.Version=v0.3.0 -X github.com/pranshuparmar/witr/internal/version.Commit=$(git rev-parse --short HEAD) -X 'github.com/pranshuparmar/witr/internal/version.BuildDate=$(date +%Y-%m-%d)'" -o witr ./cmd/witr手动安装(Unix)
# 1. 确定 OS 与架构 OS=$(uname -s | tr '[:upper:]' '[:lower:]') ARCH=$(uname -m) [ "$ARCH" = "x86_64" ] && ARCH="amd64" [ "$ARCH" = "aarch64" ] && ARCH="arm64" # 2. 下载二进制 curl -fsSL "https://github.com/pranshuparmar/witr/releases/latest/download/witr-${OS}-${ARCH}" -o witr # 3. 校验 checksum(可选) 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. 重命名并安装 chmod +x witr sudo mkdir -p /usr/local/bin sudo mv witr /usr/local/bin/witr # 5. 安装 man page(可选) 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. 确定架构 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. 下载 zip Invoke-WebRequest -Uri "https://github.com/pranshuparmar/witr/releases/latest/download/$ZipName" -OutFile "witr.zip" # 3. 解压 Expand-Archive -Path "witr.zip" -DestinationPath "." -Force # 4. 校验 checksum(可选) 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. 安装到本地 bin 目录 $InstallDir = "$env:LocalAppData\witr\bin" New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null Move-Item .\witr.exe $InstallDir\witr.exe -Force # 6. 持久化加入用户 PATH $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. 清理 Remove-Item witr.zip Remove-Item SHA256SUMS2.4 免安装运行
Nix Flake
nix run github:pranshuparmar/witr -- --helpPixi
pixi exec witr --help2.5 验证、Shell 补全与卸载
验证安装
witr --version man witrShell 补全:witr 为所有 flag 提供 tab 补全(由 internal/app/app.go 中基于 cobra 的CompletionOptions启用):
- Bash:
echo 'eval "$(witr completion bash)"' >> ~/.bashrc后source ~/.bashrc - Zsh:
echo 'eval "$(witr completion zsh)"' >> ~/.zshrc后source ~/.zshrc - Fish:
witr completion fish | source;持久化用witr completion fish > ~/.config/fish/completions/witr.fish - PowerShell:
witr completion powershell | Out-String | Invoke-Expression;持久化则加入$PROFILE
卸载:包管理器安装的用对应命令(如brew uninstall witr);脚本/手动安装的,Unix 下执行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. 命令行 Flags 全解析
运行witr --help可见完整参数。下表为 README 与 internal/app/app.go 中init()注册的全部 flags:
-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关键语义:
- 位置参数(不带 flag 的裸参数)被当作进程或服务名,可传多个。默认按子串匹配(模糊搜索),
--exact则只匹配名称完全一致(含 cmdline 中完整路径段)的进程——见 internal/target/resolve.go 的matchesExactToken,它会把命令行的每个 token 按/与\切分后做精确段匹配(例如core24可匹配参数/snap/core24/1349)。 - 所有目标 flag(
--pid、--port、--file、--container)均可重复,且可彼此混合、与位置参数混用。多个目标时结果按你输入的顺序依次输出,并以带标签的分隔线区分。所有输出模式(standard、short、tree、JSON、env、warnings、verbose)都支持多输入。这一“保持输入顺序”的解析由collectTargetsInOrder实现,它会遍历原始 argv、区分--flag=value与--flag value两种形式、跳过非目标 flag 的取值,从而把位置参数按出现位置穿插进目标列表。 --container搜索范围:跨 Docker、Podman、nerdctl、K8s/crictl、Incus、LXC、LXD 与 FreeBSD jails,按容器名、镜像、命令及 compose project/service 标签匹配(详见 internal/proc/container_detect.go 与 internal/proc/container_runtime.go)。- TUI 启动规则:不带任何参数、或未提供任何目标 flag(
--pid/--port/--file/--container)、或显式使用-i/--interactive时,进入交互模式。这一点在runApp中体现:仅当--env之外的所有目标 flag 与位置参数均为空时才进入 TUI。 - 目标的类型定义在 pkg/model/target.go:
name、pid、port、file、container五种;Resolve还会做输入合法性校验(PID 必须为正整数;端口必须在 1~65535 之间)。
4. 交互模式(TUI)
不带任何参数运行witr,或用-i显式进入,即启动基于 Bubble Tea 的终端仪表盘(见 internal/tui/model.go 等实现),提供实时刷新的四大标签页:
- Processes 标签页:所有运行中进程的实时、可排序、可过滤列表,侧面板展示高亮进程的祖先树。
- Ports 标签页:监听中的端口列表,侧面板挂载其属主进程;按
a在“仅 LISTEN”与“全部”之间切换。 - Containers 标签页:跨 Docker、Podman、nerdctl、K8s/crictl、Incus、LXC、LXD 与 FreeBSD jails 的全部运行中容器,展示名称、镜像、状态、端口、命令;每个容器还有包含挂载、网络与 compose project 元数据的详情视图。
- Locks 标签页:系统级文件锁(Linux 基于 POSIX/FLOCK,macOS/FreeBSD 基于 lsof 推导)。按
a切换到“所有打开文件”模式,锁条目会与所有值得关注的打开 fd 合并;在/中键入内容可对合并集合搜索。
TUI 还支持:进程详情(完整祖先树、子进程、环境变量、工作目录、套接字、文件上下文等)、进程操作(Unix 下直接从 UI 发送 Kill/Terminate/Pause/Resume 信号或 Renice)、鼠标支持(导航、排序列、点击行)、自适应主题(根据终端明暗背景自动适配颜色)与自动刷新(进程/端口/容器/锁列表以自适应节奏刷新,初始 3 秒,负载高时退避)。
5. 核心概念与工作原理
witr 把一切问题都归约为进程问题:端口、服务、容器、命令最终都会映射到 PID。一旦锁定 PID,witr 就构建一条因果链,解释这个 PID 为什么存在。其回答四个问题:
- 正在运行的是什么?
- 它是如何启动的?
- 是什么让它持续运行?
- 它属于什么上下文?
完整调用链(对应 internal/app/app.go 的processTarget):
- 目标解析:
target.Resolve(t, exact)把名称/端口/文件/PID 解析为候选 PID 列表;多匹配时打印候选并提示witr --pid <pid>,返回退出码 4。 - 端口特例:若端口属主为 PID 1 且 systemd 在运行,尝试
ResolveSystemdService把端口映射回 systemd 单元;若 socket 存在但属主进程不可见,则尝试ResolveContainerByPort做“端口→容器”回退(对应 README 兼容矩阵中的 “Port → Container fallback”,用于 systemd socket activation 或容器运行时占端口场景)。 - 分析管线:
pipeline.AnalyzePID执行祖先链解析(沿 PPID 向上直到 PID 1)、来源检测、子进程收集(tree/verbose 模式)、扩展信息读取(内存、I/O、fd、线程数)、restart 计数(systemdNRestarts)与警告生成。 - 来源检测:internal/source/detect.go 的
Detect按优先级依次尝试:容器 → SSH → Shell(含 tmux/screen)→ systemd → launchd → BSD rc → supervisor → cron → Windows 服务 → init → unknown。只选取一个主来源,避免误报。 - 渲染:按
--json/--warnings/--tree/--short/标准模式分别渲染(见 internal/output/standard.go 等)。
6. 实战示例输出
6.1 按名称查询
witr nodeTarget : 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 --shortsystemd (pid 1) → PM2 v5.3.1: God (pid 1481580) → python (pid 1482060)6.3 树状输出
witr --pid 143895 --treesystemd (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 个),并高亮目标进程(对应 internal/pipeline/analyze.go 中按 PID 排序收集子进程的逻辑)。
6.4 多匹配
witr ngMultiple 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>避免子串匹配、只找精确名称时用-x/--exact:
witr nginx -x6.5 文件查询
witr --file /var/lib/dpkg/lock解释持有该文件(锁)的进程。若文件被其他用户的进程持有且无权限读取,Linux 下会提示加sudo重试(见 internal/app/app.go 的handleResolveError)。
6.6 容器查询
witr --container redis按名称、镜像、命令或 compose project/service 在每一个已检测到的运行时(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) ...所有目标 flag 可重复、可混合,结果按输入顺序输出;--short、--tree、--json、--env、--warnings、--verbose均支持多输入。多目标 JSON 模式下,internal/app/app.go 会把各结果包装成 JSON 数组输出。
7. 输出行为与退出码
7.1 输出原则
- 默认单屏显示(尽力而为)
- 确定性排序(如 socket 按地址分组、端口升序、LISTEN 优先于 ESTABLISHED,见 internal/output/standard.go 的
sortSockets) - 叙事式解释
- 尽力检测,且对不确定信息明确标注
7.2 退出码
witr 返回有意义的退出码,便于脚本、CI 流水线与监控使用(常量定义在 internal/app/app.go):
| Code | 含义 |
|---|---|
| 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多目标查询时,witr 会取所有目标中最高的退出码返回,并在 stderr 说明。错误归类逻辑见classifyError:权限类错误(permission denied 等)→ 3;未找到类(no matching/not found 等)→ 2;非法输入(invalid/must specify)→ 4;其余 → 5。
7.3 标准输出的各段含义
- Target:用户查询的目标(如进程名、端口号、PID、文件路径或容器名)。
- Process:可执行文件、PID、用户、命令、启动时间与重启次数(重启次数取自 systemd
NRestarts,仅当 ≥1 时显示)。 - Why It Exists:因果祖先链,解释进程为何存在——这是 witr 的核心价值。
- Source:负责启动或监督该进程的主系统(尽力而为),只选一个。例如:
- systemd unit(Linux,含 timer 触发服务的调度信息)
- launchd service(macOS,含 schedule/trigger 详情)
- SSH 会话(含远端 IP 与终端)
- docker container
- pm2
- cron
- 交互式 Shell(可识别 tmux/screen 会话)
- Snap/Flatpak 沙箱(Linux)
- Context(尽力而为):工作目录、Git 仓库名与分支、容器名/镜像(docker、podman、kubernetes、colima、containerd)、公网/私网绑定。
- Warnings:非阻塞性观察,例如(完整规则见 internal/source/detect.go 的
Warnings函数与 README 第 7.3 节):- 进程以 root 运行
- 非 root 进程携带危险 Linux capabilities(
CAP_SYS_ADMIN、CAP_SYS_PTRACE、CAP_NET_RAW、CAP_DAC_OVERRIDE等,见源码中的dangerousCapabilities集合) - 进程监听公网接口(
0.0.0.0/::) - 服务被重启多次(超过阈值才告警;源码中阈值为
NRestarts > 5) - 高内存占用(>1GB RSS)或高 CPU(>2h 累计)
- 进程已运行超过 90 天
- 二进制文件已被删除(可能是库注入或待更新),或环境变量中出现
LD_PRELOAD/DYLD_*(潜在库注入) - 进程为 zombie(defunct)、stopped(T 状态)、工作目录可疑(
/、/tmp、/var/tmp)、容器未配置 healthcheck、服务名与进程名不匹配、无已知 supervisor 等
对于端口查询,--verbose下还会输出 socket 状态及人类可读的解释与处置建议(如TIME_WAIT提示“等待约 60s 或启用 SO_REUSEADDR”、CLOSE_WAIT提示“远端已关闭但应用未响应,通常表示资源泄漏,请重启进程”),详见 internal/source/detect.go 的EnrichSocketInfo。
8. 平台支持与功能矩阵
- Linux(x86_64、arm64):完整功能支持,基于
/proc。 - macOS(x86_64、arm64):使用
ps、lsof、sysctl、pgrep。 - Windows(x86_64、arm64):原生 Win32 API(ToolHelp32、PSAPI、Service Control Manager),不依赖 PowerShell 或 WMI,启动快且没有
Get-CimInstance卡顿问题。 - FreeBSD(x86_64、arm64):使用
procstat、ps、lsof。
8.1 特性兼容矩阵
| 特性 | Linux | macOS | Windows | FreeBSD | 备注 |
|---|---|---|---|---|---|
| 进程选择 | |||||
| 按名称 | ✅ | ✅ | ✅ | ✅ | |
| 按 PID | ✅ | ✅ | ✅ | ✅ | |
| 按端口 | ✅ | ✅ | ✅ | ✅ | |
| 按文件 | ✅ | ✅ | ✅ | ✅ | |
| 按容器 | ✅ | ✅ | ✅ | ✅ | 要求运行时 CLI 在 PATH 中(docker/podman/nerdctl/crictl/incus/lxc/lxc-ls/jls) |
| 多输入/混合输入 | ✅ | ✅ | ✅ | ✅ | 可重复 flag、可混类型 |
| 精确匹配 | ✅ | ✅ | ✅ | ✅ | |
| 完整命令行 | ✅ | ✅ | ✅ | ✅ | |
| 进程启动时间 | ✅ | ✅ | ✅ | ✅ | |
| 工作目录 | ✅ | ✅ | ✅ | ✅ | |
| 环境变量 | ✅ | ⚠️ | ⚠️ | ✅ | macOS 受 SIP 限制;Windows 受保护进程不可访问 |
| 网络 | |||||
| 监听端口 | ✅ | ✅ | ✅ | ✅ | |
| 绑定地址 | ✅ | ✅ | ✅ | ✅ | |
| 端口→PID 解析 | ✅ | ✅ | ✅ | ✅ | |
| 端口→容器回退 | ✅ | ✅ | ✅ | ✅ | 当端口属主为 PID 1(systemd socket activation)或容器运行时时使用 |
| 服务检测 | |||||
| 服务管理器 | ✅ | ✅ | ✅ | ✅ | Linux: systemd;macOS: launchd;Windows: Services;FreeBSD: rc.d |
| 服务描述 | ✅ | ✅ | ✅ | ✅ | Linux:Description;macOS:Comment;Windows:Display Name;FreeBSD:rc头 |
| 配置来源 | ✅ | ✅ | ✅ | ✅ | Linux: Unit File;macOS: Plist;Windows: Registry Key;FreeBSD: Rc Script |
| Supervisor | ✅ | ✅ | ✅ | ✅ | |
| 容器 | ✅ | ✅ | ✅ | ✅ | Docker(含 compose 映射)、Podman、nerdctl、K8s(Kubepods/crictl)、Containerd;macOS/Linux 的 Colima;Linux 的 Incus/LXC/LXD;FreeBSD 的 Jails |
| SSH 会话检测 | ✅ | ✅ | ✅ | ✅ | 可识别远端 IP 与终端 |
| tmux/screen 检测 | ✅ | ✅ | ❌ | ✅ | Source 中展示会话名 |
| 调度检测 | ✅ | ✅ | ❌ | ❌ | Linux: systemd timers;macOS: launchd intervals/calendar |
| Snap/Flatpak 检测 | ✅ | ❌ | ❌ | ❌ | |
| 健康与诊断 | |||||
| CPU 使用检测 | ✅ | ✅ | ✅ | ✅ | |
| 内存使用检测 | ✅ | ✅ | ✅ | ✅ | |
| 健康状态检测 | ✅ | ✅ | ✅ | ✅ | |
| 打开文件/句柄 | ✅ | ✅ | ⚠️ | ✅ | Windows 仅计数 |
| 文件锁 | ✅ | ✅ | ❌ | ✅ | Linux:/proc/locks;macOS/FreeBSD: 由lsof/fstat推导 |
| 已删除二进制检测 | ✅ | ✅ | ✅ | ✅ | 可执行文件缺失时告警 |
| Capability 告警 | ✅ | ❌ | ❌ | ❌ | 非 root 进程携带危险 capability 时告警 |
| 上下文 | |||||
| Git 仓库/分支检测 | ✅ | ✅ | ✅ | ✅ | |
| 交互模式(TUI) | |||||
| Processes 标签页 | ✅ | ✅ | ✅ | ✅ | |
| Ports 标签页 | ✅ | ✅ | ✅ | ✅ | |
| Containers 标签页 | ✅ | ✅ | ✅ | ✅ | |
| Locks 标签页 | ✅ | ✅ | ❌ | ✅ | 按a显示所有打开文件 |
| 进程详情 | ✅ | ✅ | ✅ | ✅ | |
| 进程操作 | ✅ | ✅ | ❌ | ✅ |
图例:✅ 完整支持 | ⚠️ 部分/有限支持 | ❌ 不可用
8.2 权限说明
- Linux/FreeBSD:witr 需要检查系统目录,可能需要提权;信息不全时用
sudo witr [你的参数]。 - macOS:依赖
ps、lsof、launchctl,部分操作需要提权(sudo witr ...);因 System Integrity Protection(SIP),即使 sudo 也可能无法访问部分系统进程细节。 - Windows:直接调用 Win32 API,无需 PowerShell/WMI。要查看其他用户属主进程或系统服务的详情,必须以管理员身份运行终端(
.\witr.exe [你的参数])。
9. 成功标准与适用场景
witr 的成败标准(见 README 第 9 节)是:用户在数秒内回答“为什么它在运行”;减少对多个工具的依赖;在压力(故障排查)场景下输出仍然可读;用户信任它在事故处理中的结论。
典型适用场景包括:定位突然占用的端口到底属于谁、找出被 supervisor 层层拉起的神秘进程、排查容器内进程的启动来源、判断某个文件锁被哪个进程持有、在 CI/监控脚本中用退出码快速判定服务状态,以及在--json模式下做机器可读的进程归因分析。
10. 延伸阅读
- 完整命令行手册:docs/cli/witr.1(roff 格式)与 docs/cli/witr.md(Markdown 格式),两者均由 internal/tools/docgen 生成。
- 源码入口与 CLI 装配:main.go、cmd/witr/main.go、internal/app/app.go。
- 分析管线与祖先链:internal/pipeline/analyze.go、internal/proc/ancestry.go。
- 来源检测与警告规则:internal/source/detect.go。
- 目标解析与校验:internal/target/resolve.go、pkg/model/target.go。
- 输出渲染:internal/output/standard.go 等。
- 交互模式 TUI:internal/tui/model.go 等。
- 容器运行时检测:internal/proc/container_detect.go、internal/proc/container_runtime.go。
- 浏览器端模拟演练:仓库 docs/index.html 及 docs/js 下的前端实现提供了一套模拟 Linux 环境的引导式教程与自由演练沙箱,无需安装即可体验 TUI 与 CLI 的实际输出效果。
【免费下载链接】witrWhy is this running? Trace any process, port, container, or file back to what started it - CLI + TUI.项目地址: https://gitcode.com/GitHub_Trending/wi/witr
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考