@GoJun315: 终端工具用了 20 年,一直没人搞懂进程为什么在跑。 一位印度独立开发者,开源了 witr 工具,上线不到五个月,暴涨了 15400+ GitHub Star! 终端里一行命令,把进程的整条来路说清楚。从 kernel 到 systemd…
摘要
一款名为 witr 的开源终端工具,由印度独立开发者开发,能解释进程为何运行,从 kernel 到 systemd 追踪进程来源,并内置交互式 TUI 仪表盘,上线不到五个月获得 15400+ GitHub Star。
查看缓存全文
缓存时间: 2026/05/14 16:40
终端工具用了 20 年,一直没人搞懂进程为什么在跑。 一位印度独立开发者,开源了 witr 工具,上线不到五个月,暴涨了 15400+ GitHub Star! 终端里一行命令,把进程的整条来路说清楚。从 kernel 到 systemd unit,从开放端口追回绑定它的进程,这条链路以前得靠手动拼。 - 可疑进程、监听公网端口、静默跑了几个月的内存占用,全会主动标出来 - 内置交互式 TUI 仪表盘,不用死记命令参数 - 按进程名、PID、端口、文件路径都能查,结果用人话输出,不是一堆看不懂的技术流水 GitHub:https://github.com/pranshuparmar/witr… 支持 Linux、macOS、Windows、FreeBSD 等主流系统均可安装。 经常接手陌生服务器、排查线上故障的开发者和运维,值得装一个。
pranshuparmar/witr
Source: https://github.com/pranshuparmar/witr
Purpose • Installation • ✨ TUI • Flags • Examples • Platforms
Goals • Core Concept • Output Behavior • Success Criteria • Sponsors
1. Purpose
witr exists to answer a single question:
Why is this running?
When something is running on a system, whether it is a process, a service, or something bound to a port, there is always a cause. That cause is often indirect, non-obvious, or spread across multiple layers such as supervisors, containers, services, or shells.
Existing tools (ps, top, lsof, ss, systemctl, docker ps) expose state and metadata. They show what is running, but leave the user to infer why by manually correlating outputs across tools.
witr makes that causality explicit.
It explains where a running thing came from, how it was started, and what chain of systems is responsible for it existing right now, in a single, human-readable output or an interactive TUI dashboard.
2. Installation
witr is distributed as a single static binary for Linux, macOS, FreeBSD, and Windows.
witr is also independently packaged and maintained across multiple operating systems and ecosystems. An up-to-date overview of packaging status is available on Repology. Please note that community packages may lag GitHub releases due to independent review and validation.
If you use a package manager (Homebrew, Conda, Winget, etc.), we recommend installing via that for easier updates. Otherwise, the install script is the quickest way to get started.
2.1 Quick Install
Unix (Linux, macOS & FreeBSD)
curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash
Script Details
The script will:
- Detect your operating system (
linux,darwinorfreebsd) - Detect your CPU architecture (
amd64orarm64) - Download the latest released binary and man page
- Install it to
/usr/local/bin/witr - Install the man page to
/usr/local/share/man/man1/witr.1 - Pass INSTALL_PREFIX to override default install path
Windows (PowerShell)
irm https://raw.githubusercontent.com/pranshuparmar/witr/main/install.ps1 | iex
Script Details
The script will:
- Download the latest release (zip) and verify checksum.
- Extract
witr.exeto%LocalAppData%\witr\bin. - Add the bin directory to your User
PATH.
2.2 Package Managers
Conda (macOS, Linux & Windows) 
You can install witr using conda, mamba, or pixi on macOS, Linux, and Windows:
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) 
On Arch Linux and derivatives, install from the AUR package:
yay -S witr-bin
# alternatively using paru
paru -S witr-bin
# or use your preferred AUR helper
FreeBSD Ports 
You can install witr on FreeBSD from the FreshPorts port:
pkg install witr
# or
pkg install sysutils/witr
Or build from Ports:
cd /usr/ports/sysutils/witr/
make install clean
Aqua (macOS, Linux & Windows) 
You can install witr using aqua:
# Add package
aqua g -i pranshuparmar/witr
# Install package
aqua i pranshuparmar/witr
Prebuilt Packages (deb, rpm, apk)
witr provides native packages for major Linux distributions. You can download the latest .deb, .rpm, or .apk package from the GitHub releases page.
-
Generic download command using
curl:# Replace <package name with the actual package that you need> curl -LO https://github.com/pranshuparmar/witr/releases/latest/download/<package-name> -
Debian/Ubuntu (.deb):
sudo dpkg -i ./witr-*.deb # Or, using apt for dependency resolution: 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 Source & Manual Installation
Go (cross-platform)
You can install the latest version directly from source:
go install github.com/pranshuparmar/witr/cmd/witr@latest
This will place the witr binary in your $GOPATH/bin or $HOME/go/bin directory. Make sure this directory is in your PATH.
Manual Installation
If you prefer manual installation, follow these simple steps for your platform:
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 Run Without Installation
Nix Flake
If you use Nix, you can build witr from source and run without installation:
nix run github:pranshuparmar/witr -- --help
2.5 Other Operations
Verify Installation
witr --version
man witr
Shell Completions
witr supports tab completion for all flags. To enable it, add the appropriate line to your shell configuration:
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
Uninstallation
If you installed via a package manager (Homebrew, Conda, etc.), please use the respective uninstall command (e.g., brew uninstall witr).
To completely remove script/manual installation of 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. Interactive Mode (TUI)
Running witr without any arguments or with the -i flag launches the Interactive Mode (TUI). This provides a real-time, terminal-based dashboard for exploring processes and ports.
Key Features:
- Live Process List: Real-time view of all running processes with sorting and filtering.
- Port View: Explore open ports and immediately see which processes are holding them.
- Process Details: Deep-dive into a specific process to see its full ancestry tree, child processes, environment variables, working directory, and more.
- Process Actions: Send signals (Kill, Terminate, Pause, Resume) or Renice processes directly from the UI.
- Mouse Support: Navigate, sort columns, and click rows using your mouse.
4. Flags & Options
--env show environment variables for the process
-x, --exact use exact name matching (no substring search)
-f, --file strings file path(s) to find process for (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
Positional arguments (without flags) are treated as process or service names. Multiple names can be passed. By default, name matching uses substring matching (fuzzy search). Use --exact to match only processes with the exact name.
All target flags (--pid, --port, --file) are repeatable and can be mixed with each other and with positional name arguments. When multiple targets are provided, results are shown sequentially with labeled dividers. All output modes (standard, short, tree, JSON, env, warnings, verbose) work with multiple inputs.
The TUI is launched if no arguments or relevant flags (--pid, --port, --file) are provided, or if the --interactive flag is explicitly used.
5. Example Outputs
5.1 Name Based Query
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)
Restarts : 1
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)
Listening : 127.0.0.1:5001
5.2 Short Output
witr --port 5000 --short
systemd (pid 1) → PM2 v5.3.1: God (pid 1481580) → python (pid 1482060)
5.3 Tree Output
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)
Note: Tree view includes child processes (up to 10) and highlights the target process.
5.4 Multiple Matches
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>
To avoid substring matching and only find processes with an exact name, use the --exact flag:
witr nginx -x
5.5 File Based Query
witr --file /var/lib/dpkg/lock
Explains the process holding a file open.
5.6 Multiple Inputs
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)
...
All target flags are repeatable and can be mixed. Results appear in the order you typed them. All output modes (--short, --tree, --json, --env, --warnings, --verbose) work with multiple inputs.
6. Platform Support
- Linux (x86_64, arm64) - Full feature support (
/proc). - macOS (x86_64, arm64) - Uses
ps,lsof,sysctl,pgrep. - Windows (x86_64, arm64) - Uses
Get-CimInstance,tasklist,netstat. - FreeBSD (x86_64, arm64) - Uses
procstat,ps,lsof.
5.1 Feature Compatibility Matrix
| Feature | Linux | macOS | Windows | FreeBSD | Notes |
|---|---|---|---|---|---|
| Process Selection | |||||
| By Name | ✅ | ✅ | ✅ | ✅ | |
| By PID | ✅ | ✅ | ✅ | ✅ | |
| By Port | ✅ | ✅ | ✅ | ✅ | |
| By File | ✅ | ✅ | ❌ | ✅ | |
| Multiple/mixed inputs | ✅ | ✅ | ✅ | ✅ | Repeatable flags, mixed types. |
| Exact Match | ✅ | ✅ | ✅ | ✅ | |
| Full command line | ✅ | ✅ | ✅ | ✅ | |
| Process start time | ✅ | ✅ | ✅ | ✅ | |
| Working directory | ✅ | ✅ | ✅ | ✅ | |
| Environment variables | ✅ | ⚠️ | ❌ | ✅ | macOS: Partial support due to SIP restrictions. |
| Network | |||||
| Listening ports | ✅ | ✅ | ✅ | ✅ | |
| Bind addresses | ✅ | ✅ | ✅ | ✅ | |
| Port → PID resolution | ✅ | ✅ | ✅ | ✅ | |
| Service Detection | |||||
| Service Manager | ✅ | ✅ | ✅ | ✅ | Linux: systemd, macOS: launchd, Windows: Services, FreeBSD: rc.d |
| Service Description | ✅ | ✅ | ✅ | ✅ | Linux: Description, macOS: Comment, Windows: Display Name, FreeBSD: rc header |
| Configuration Source | ✅ | ✅ | ✅ | ✅ | Linux: Unit File, macOS: Plist, Windows: Registry Key, FreeBSD: Rc Script |
| Supervisor | ✅ | ✅ | ✅ | ✅ | |
| Containers | ✅ | ✅ | ✅ | ✅ | Docker (plus Compose mappings), Podman, K8s (Kubepods), Containerd. Colima on macOS/Linux. Jails on FreeBSD. |
| SSH session detection | ✅ | ✅ | ✅ | ✅ | Detects remote IP and terminal. |
| tmux/screen detection | ✅ | ✅ | ❌ | ✅ | Shows session name in source. |
| Schedule detection | ✅ | ✅ | ❌ | ❌ | Linux: systemd timers, macOS: launchd intervals/calendar. |
| Snap/Flatpak detection | ✅ | ❌ | ❌ | ❌ | |
| Health & Diagnostics | |||||
| CPU usage detection | ✅ | ✅ | ✅ | ✅ | |
| Memory usage detection | ✅ | ✅ | ✅ | ✅ | |
| Health status detection | ✅ | ✅ | ✅ | ✅ | |
| Open Files / Handles | ✅ | ✅ | ⚠️ | ✅ | Windows: count only. |
| Deleted binary detection | ✅ | ✅ | ✅ | ✅ | Warns if executable is missing. |
| Capability warnings | ✅ | ❌ | ❌ | ❌ | Warns about dangerous capabilities on non-root processes. |
| Context | |||||
| Git repo/branch detection | ✅ | ✅ | ✅ | ✅ | |
| Interactive Mode (TUI) | |||||
| Process Dashboard | ✅ | ✅ | ✅ | ✅ | |
| Port Dashboard | ✅ | ✅ | ✅ | ✅ | |
| Process Details | ✅ | ✅ | ✅ | ✅ | |
| Process Actions | ✅ | ✅ | ❌ | ✅ |
Legend: ✅ Full support | ⚠️ Partial/limited support | ❌ Not available
5.2 Permissions Note
Linux/FreeBSD
witr inspects system directories which may require elevated permissions.
If you are not seeing the expected information, try running witr with sudo:
sudo witr [your arguments]
macOS
On macOS, witr uses ps, lsof, and launchctl to gather process information. Some operations may require elevated permissions:
sudo witr [your arguments]
Note: Due to macOS System Integrity Protection (SIP), some system process details may not be accessible even with sudo.
Windows
On Windows, witr uses Get-CimInstance, tasklist, and netstat. To see details for processes owned by other users or system services, you must run the terminal as Administrator.
# Run in Administrator PowerShell
.\witr.exe [your arguments]
7. Goals
Primary goals
- Explain why a process exists, not just that it exists
- Reduce time‑to‑understanding during debugging and outages
- Work with zero configuration
- Be safe, read‑only, and non‑destructive
- Prefer clarity over completeness
Non‑goals
- Not a monitoring tool
- Not a performance profiler
- Not a replacement for systemd/docker tooling
- Not a remediation or auto‑fix tool
8. Core Concept
witr treats everything as a process question.
Ports, services, containers, and commands all eventually map to PIDs. Once a PID is identified, witr builds a causal chain explaining why that PID exists.
At its core, witr answers:
- What is running?
- How did it start?
- What is keeping it running?
- What context does it belong to?
9. Output Behavior
9.1 Output Principles
- Single screen by default (best effort)
- Deterministic ordering
- Narrative-style explanation
- Best-effort detection with explicit uncertainty
9.2 Exit Codes
witr returns meaningful exit codes for use in scripts, CI pipelines, and monitoring:
| Code | Meaning |
|---|---|
| 0 | Clean: process found, no warnings |
| 1 | Warnings: process found but has one or more warnings |
| 2 | Not found: no matching process or service |
| 3 | Permission denied: insufficient privileges |
| 4 | Invalid input: bad arguments or ambiguous match |
Example Usage:
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" ;;
esac
9.3 Standard Output Sections
Target
What the user asked about.
Process
Executable, PID, user, command, start time and restart count.
Why It Exists
A causal ancestry chain showing how the process came to exist. This is the core value of witr.
Source
The primary system responsible for starting or supervising the process (best effort).
Examples:
- systemd unit with schedule info for timer-triggered services (Linux)
- launchd service with schedule/trigger details (macOS)
- SSH session (with remote IP and terminal)
- docker container
- pm2
- cron
- interactive shell (detects tmux/screen sessions)
- Snap/Flatpak sandbox (Linux)
Only one primary source is selected.
Context (best effort)
- Working directory
- Git repository name and branch
- Container name / image (docker, podman, kubernetes, colima, containerd)
- Public vs private bind
Warnings
Non‑blocking observations such as:
- Process is running as root
- Dangerous Linux capabilities on non-root processes (CAP_SYS_ADMIN, etc.)
- Process is listening on a public interface (0.0.0.0 / ::)
- Restarted multiple times (warning only if above threshold)
- Process is using high memory (>1GB RSS)
- Process has been running for over 90 days
- Deleted binary, library injection indicators (LD_PRELOAD, DYLD_*)
10. Success Criteria
witr is successful if:
- A user can answer “why is this running?” within seconds
- It reduces reliance on multiple tools
- Output is understandable under stress
- Users trust it during incidents
11. Sponsors
Special thanks to the people supporting witr ❤️
相似文章
@laobaishare: 牛 x 啊,一个印度独立开发者, 做出了一个被程序员忽视了 20 年的终端工具。 名字叫 witr。 它能回答一个你的操作系统始终拒绝回答的问题: 为什么这个进程正在运行?
一个印度独立开发者发布了一款名为wit的终端工具,解决了操作系统长期未能回答的问题:为什么某个进程正在运行。
@jakevin7: OpenCLI 2W star 了 ,https://github.com/jackwener/OpenCLI… 不过现在对 star 数已经没什么感觉了。 最开心的时候,还是和用户们交流使用&分享心得经验的时候。 后面还会持续改进,让 …
OpenCLI 项目 GitHub 星标突破 2 万,该工具可将网站、浏览器会话及 Electron 应用转化为确定性 CLI 接口,支持 AI Agent 直接操作浏览器并自动化工作流。
@berryxia: 兄弟们! 不要重复造轮子,直接拿这个31.4K Star的开源来干吧! 字节跳动把 UI-TARS-desktop 开源了,看了一眼,这个项目已经上线快一年了! 目前 Star 数已经来到 31.4k,而且增长速度还挺稳。 24 小时增长…
ByteDance open-sourced UI-TARS-desktop, a native desktop GUI agent with 31.4k GitHub stars that uses vision models to control local or remote applications via natural language. The tool runs locally for privacy, supports Windows and macOS, and includes a CLI with streaming output for developers.
@VincentLogic: 发现个字节开源的桌面 AI 神器! UI-TARS Desktop,31k stars 不是吹的,这玩意儿真能看懂你的屏幕,然后帮你自动操作电脑。 你告诉它"帮我把 VS Code 的自动保存打开,延迟改成 500 毫秒",它就自己: -…
字节跳动开源的桌面 AI 自动化工具 UI-TARS Desktop 支持本地运行与屏幕视觉理解,可通过自然语言指令自主操控电脑完成日常任务。
@VincentLogic: 发现个终端里的网络监控神器! RustNet,在终端里就能实时监控所有网络连接,哪个进程在偷偷传数据、服务器被谁连了,一眼看清。 最爽的是能看到每个连接对应的应用程序,这点 Wireshark 都做不到。SSH 连服务器直接看,不用搞 X…
介绍了 RustNet,一款基于 Rust 开发的终端网络监控工具,支持实时监控网络连接、进程关联及流量分析,适用于运维和安全排查。