
witr: The One-Stop Tool That Uncovers Why Any Process or Port Is Running
TL;DR
- Find the process that owns any port in a single command.
- Get exact start time, binary path, and ancestry instantly.
- Detect devshm binaries and public-bind warnings.
- Export JSON for scripts or alerting.
- Cut investigation time from minutes of tool-hopping to seconds.
Table of Contents
Why this matters
I once chased a mysterious port on a production box. I ran ss -tulpn, got port 443, then used lsof -i :443 and ps -p
Core concepts
witr, short for “Why Is This Running?”, works on Linux, macOS, Windows, and FreeBSD. It does three things: target resolution, ancestry building, and warnings & context.
Target resolution – Accepts a PID, port number, or name. Internally it scans /proc/net/tcp, /proc//comm*, /proc//cmdline*, and falls back to systemctl for units. That means witr –port 8080 or witr nginx yields the same level of insight.witr — Usage Examples | pranshuparmar/witr | DeepWiki (2025)
Ancestry building – Walks the parent chain up to PID 1, capturing working directory and Git repo if any. Output shows the chain, e.g., systemd (pid 1) → nginx (pid 1234) with exact start time: Tue 2025-02-02 11:42:10 +05:30.witr — witr: Uncover Why Processes Are Running on Your System (2025)
Warnings & context – Flags suspicious patterns: binaries in devshm, root-owned processes, public interface binds (0.0.0.0/::), or long-running processes. The –json flag exports the full model for SIEMs or scripts.witr — witr — Why is this running? (2025)
All is a single static binary, no daemon, no privileged install. Written in Go, statically linked, released under Apache-2.0.
How to apply it
1. Install witr
brew install witr # macOS / Linux via Homebrew
sudo apt install witr # Debian/Ubuntu from releases
curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash
The script downloads the binary to /usr/local/bin.
2. Investigate a port
witr --port 80
Sample output (excerpt):witr — Usage Examples | pranshuparmar/witr | DeepWiki (2025)
Target : --port 80
Process : nginx (pid 9876)
User : root
Command : /usr/sbin/nginx -g daemon off;
Started : 2 hours ago (Tue 2025-02-02 09:12:00 +05:30)
Why It Exists : systemd (pid 1) → nginx (pid 9876)
Source : systemd
Working Dir : /etc/nginx
Listening : 0.0.0.0:80
Warnings : Process is listening on a public interface (0.0.0.0/::)
Notice the exact start time and public-bind warning.
3. Export JSON for automation
witr --port 80 --json > port80.json
Feed JSON to SIEM or CI.
4. Quick one-liner or tree view
witr --port 80 --short # → systemd (pid 1) → nginx (pid 9876)
witr --port 80 --tree # ASCII tree of ancestry
5. Handling multiple listeners
witr prompts to choose if multiple processes listen on a port.
6. Systemd unit file
Running witr nginx outputs:
Unit file : /lib/systemd/system/nginx.service
7. Feeding ACLI
Feed witr’s JSON output into ACLI’s policy engine.
Table 1: Target Types Comparison
| Target Type | Use Case | Limitation |
|---|---|---|
| PID | Direct lookup | Requires PID knowledge, may be stale |
| Port | Owner of listening socket | Needs elevated privileges |
| Name | Process or service name | Ambiguous if many instances |
Table 2: Output Formats
| Format | Description | Ideal Use |
|---|---|---|
| Standard | Narrative with six sections | Interactive debugging |
| Short | One-liner ancestry chain | Scripts, aliases |
| Tree | ASCII tree | Visual inspection |
| JSON | Machine-readable model | CI, monitoring, alerts |
Pitfalls & edge cases
- Container internals: relies on host’s /proc; sandboxed processes may appear only at top-level.
- Multiple listeners: prompts to choose.
- Non-interactive shells: infers launching shell via PPID; reports systemd if top-level.
- High process count: initial resolution can take a few seconds.
- Missing privileges: normal users may see “socket found but owning process not detected”; re-run with sudo.
- Limited Windows support: beta; test on staging.
Open questions:
- Origin of command for non-interactive shells? witr uses PPID chain and ExecStart of systemd units.
- Inspecting containers or virtualization? Yes, reads /proc/
/cgroup . - Handling multiple processes on same port? Prompts for choice, flags public interface binds.
- Integration with systemd journal? Unit file path displayed; can run systemctl status manually.
- Overhead on large system? ~0.9 seconds on 32-core server with 20 k processes.
Quick FAQ
| Question | Answer |
|---|---|
| What is witr? | CLI that explains why a process, service, or port is running, with ancestry, start time, and warnings. |
| Does witr work on Windows? | Has a Windows binary; support is experimental. Test before production use. |
| Can I export results to JSON? | Yes, use –json. |
| How does witr find a process start time? | Reads /proc/ |
| What about binaries in devshm? | Flags them as suspicious. |
| Can I debug an SSH service? | Run witr sshd. |
| Does witr need root privileges? | Not for most queries; privileged ports require sudo. |
Conclusion
witr turns chaotic process-investigation into a single narrative. It saves time, letting admins focus on remediation. If comfortable with ps, lsof, and ss, witr is a natural next step.
Next steps
- Install witr on a test node.
- Run witr –port
and review output. - Use –json to feed into monitoring.
- Create short alias alias w= witr –short for quick checks.
For small fleets or single machines, witr feels like a magic magnifying glass. For large, dynamic environments, pair it with existing monitoring. Either way, witr is a solid addition to any Linux admin’s toolkit.

