7 Powerful witr Command Examples: Find Why Any Process Is Running on Linux

The witr command answers one question that ps, top, and systemctl all dance around: why is this thing running? The name literally stands for “Why Is This Running”. Point it at a process name, a PID, a port, or a container, and it prints the full causal chain that explains how the process came to exist, who started it, and what keeps it alive.

I found witr while chasing a stray Node process that kept binding port 5001 on a staging box. Running ps aux told me the process existed. Running witr told me pm2 spawned it from a systemd unit two days earlier, along with the working directory and the git branch it was launched from. That chain took one command instead of five.

The project sits at over 18,000 stars on GitHub and landed in the official Debian and Ubuntu repositories, which is fast for a tool this young. Here are seven ways I use it.

Install the witr Command on Linux

On Ubuntu 26.04+, Debian sid, and Kali Linux, install straight from the repos:

sudo apt install witr

Homebrew and Arch users have it too:

brew install witr
yay -S witr-bin

For everything else there is a single static binary. The install script detects your OS and CPU architecture, then drops the binary into /usr/local/bin along with a man page:

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

The binary runs on Linux, macOS, FreeBSD, and Windows. Verify the install with witr --version. Shell completions exist for bash, zsh, fish, and PowerShell. For bash, add eval "$(witr completion bash)" to your .bashrc. The full list of package managers, including conda, npm, winget, and Nix, lives in the witr GitHub repository.

1. Ask Why a Process Runs with the witr Command

The simplest invocation takes a process name:

witr node

The output reads like an incident report. You get the PID, the user, the exact command line, and when it started. Then comes the part no other tool gives you in one shot, a “Why It Exists” chain:

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)

Name matching uses substring search by default, so witr ng matches nginx and ngrok. If multiple processes match, witr lists them all with PIDs and asks you to pick one. Pass -x for exact matching when you want only nginx and nothing else.

2. Trace a Port Back to Its Owner

Something holds port 5000 and you have no idea what. The classic route is ss -tlnp, then ps on the PID, then reading the parent chain by hand. The witr command collapses that into one line:

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

The --short flag prints just the ancestry chain, which I find perfect for pasting into a ticket. This pairs well with packet-level work. When I need to see what that process actually sends over the wire, I switch to tcpdump.

3. Print a Full Ancestry Tree

The --tree flag turns the chain into a tree with child processes included:

witr --pid 143895 --tree
systemd (pid 1)
  └─ bash (pid 143860)
    └─ sh (pid 143886)
      └─ node (pid 143895)
        ├─ node (pid 143930)
        └─ node (pid 144189)

The target process gets highlighted, and up to ten children appear under it. This view saved me real time debugging a build script that forked workers and refused to die cleanly.

4. Find Who Holds a File Lock

Every Debian admin has hit “could not get lock /var/lib/dpkg/lock”. The usual fix involves lsof and some guessing. With witr:

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

The witr command names the process holding the file open and explains where that process came from. No more blindly killing apt processes and hoping.

5. Inspect Containers Across Runtimes

The --container flag searches Docker, Podman, nerdctl, K8s/crictl, Incus, LXC, LXD, and FreeBSD jails in one query:

witr --container redis --verbose

It matches against container name, image, command, and compose labels. With --verbose you also get mounts, networks, and compose project metadata. On hosts running a mix of Docker and Podman, this beats remembering two different CLI syntaxes.

6. Mix Targets in One Query with the witr Command

All target flags are repeatable and combinable. This is where the witr command stops being a toy and becomes a triage tool:

witr nginx --port 5432 --pid 1234

Each target gets its own labeled section in the output. Add --json and you can feed the whole thing into jq for scripting or monitoring pipelines. The --env flag dumps the process environment variables, and --warnings shows only the suspicious findings.

7. Explore Live with the Interactive TUI

Run the witr command with no arguments and it launches a terminal dashboard with four tabs: Processes, Ports, Containers, and Locks. Each process row shows its ancestry tree in a side panel. You can sort columns, filter with /, and even send signals (kill, terminate, pause, resume) or renice directly from the UI on Unix systems.

The list refreshes every 3 seconds, backing off under load, and the colors adapt to light or dark terminals. It will not replace htop for watching CPU and memory, but for answering “what is this and where did it come from”, the TUI wins.

When Not to Use the witr Command

witr explains process origin, not process behavior. If you need to know what syscalls a process makes, that is strace territory. If you need resource usage over time, use a monitor like btop or htop. And on locked-down systems, some details (environment variables, other users’ processes) require root, so run it with sudo when the output looks thin.

There is also no history. The witr command reports the current state of the process table. If the process died before you ran it, there is nothing to trace. For that you want auditd or process accounting.

Verdict

The witr command earned a permanent spot in my server toolkit within a week. It replaces a five-step ps, ss, lsof, systemctl, docker-ps ritual with a single readable answer. The static binary installs in seconds, the man page is short, and the packaging coverage on Repology keeps growing.

Next time a mystery process shows up on one of your boxes, skip the manual detective work. Ask witr why it is running.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts