Find a process ID by name
Look up the PID(s) of a running process given its executable name — the lookup that precedes most kill / signal / inspect operations.
How to find a process id by name in each shell
pgrep -x nginx`-x` requires EXACT match against argv[0]. Without it, `pgrep nginx` also matches `nginx-proxy`, `gunicorn` (if cmdline contains "nginx"), etc. Use `-f` to match the full command line, `-l` to print name alongside.
pgrep -x nginxpgrep -x nginx(Get-Process -Name nginx -ErrorAction SilentlyContinue).Id`-Name` matches against `ProcessName` (the .exe filename without extension). Returns multiple PIDs when multiple instances run; `-ErrorAction SilentlyContinue` avoids the "Cannot find a process" error on zero matches.
tasklist /fi "imagename eq nginx.exe" /nh /fo csv`/nh` strips the header row; `/fo csv` makes it parseable (PID is the second comma-separated field). Without `.exe`, the filter matches nothing — Windows always includes the extension in `imagename`.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **`pgrep -x` vs `-f` is the most common source of "wrong PID" bugs**: by default `pgrep` matches `nginx` against argv[0] (the program name). With `-x` the entire argv[0] must equal the pattern (no partial). With `-f` the pattern is matched against the FULL command line (argv concatenated with spaces). For `java -jar myapp.jar`, the argv[0] is `java` — only `pgrep -f myapp` finds it; `pgrep java` returns every JVM (IDE, build, app, sbt, etc.). Anti-pattern: `pgrep myapp` for a Java/Python/Node app — you'll either miss it or match siblings.
- **`pidof` is Linux-only (procps-ng package)** and matches only the binary basename (`pidof nginx` returns nothing for `/usr/local/bin/my-nginx-wrapper` even if it's the only one running). It's strictly less flexible than `pgrep`; the one advantage is that it returns ALL PIDs space-separated on one line (handy for `kill $(pidof nginx)`). BSD/macOS has no `pidof` — use `pgrep` (present everywhere) or `ps -o pid= -C nginx` (GNU `-C` flag — also not on BSD).
- **pwsh `Get-Process -Name nginx` is case-INSENSITIVE on Windows, case-SENSITIVE on Linux/macOS** when running PowerShell 7. This catches scripts moving between platforms. Workaround: lowercase the filter (`Get-Process | Where-Object Name -eq "nginx"`) — `Where-Object` follows the same case rules as `-eq` (insensitive by default; use `-ceq` for case-sensitive). For the FULL command line (analogous to `pgrep -f`), pwsh requires a CIM query: `Get-CimInstance Win32_Process -Filter "CommandLine LIKE \'%myapp%\'" | Select-Object ProcessId, CommandLine` — slower than `Get-Process` but exposes the command line that `Get-Process` does NOT.
- **Self-exclusion**: `pgrep -x bash` from a bash script returns the script's OWN PID alongside whatever else you wanted. Excluding self: `pgrep -x bash | grep -v ^$$\$` or pass `--newest`/`--oldest` to pick a single one. Same trap with `pgrep -f myscript.sh` — the running grep process and the script process both match. Use `pgrep -f myscript.sh | grep -v $$` or `pidof -o $$ myscript.sh` (`-o` excludes a PID).
- **For "exactly one PID expected" assertions**: `pgrep -x nginx | wc -l` should be 1 — wrap in a check: `[ "$(pgrep -x nginx | wc -l)" -eq 1 ] || { echo "expected exactly 1 nginx"; exit 1; }`. pwsh: `@(Get-Process -Name nginx).Count -eq 1`. Bare `(Get-Process -Name nginx).Count` returns `$null` when no matches (no auto-unwrap to array of 0) — always coerce with `@(…)`. This single-PID check is critical for `kill -HUP $(pidof X)` patterns where killing two PIDs has different semantics than killing one (config reload vs accidental cross-traffic-restart).
Related commands
Related tasks
- Kill a process by name— Terminate every running process whose executable matches a given name.
- Kill the process listening on a port— Find and terminate whatever process is bound to a TCP/UDP port — the answer to "address already in use" when a previous run did not release the socket.
- Send a signal to a process— Deliver a specific Unix signal to a process — useful for graceful shutdown, config reload, and triggered behaviour.
- Show the process tree— Render the parent/child relationships between running processes — useful for tracing rogue children, debugging fork bombs, and understanding shell-spawned subprocess chains.