pidof — Return PID(s) by exact process name — Linux-only cousin of pgrep across all 5 shells
Equivalents in every shell
pidof firefoxPart of `sysvinit-utils` (or `procps` in some distros). Prints space-separated PIDs on one line — perfect for `kill -9 $(pidof firefox)`. `-s` returns just the single oldest (the parent for forking servers); `-x` matches scripts (so `pidof script.sh` works for shell scripts, not just compiled binaries). LINUX-ONLY — does not exist on macOS or BSD by default.
pidof firefoxSame external on Linux zsh. On macOS, `pidof` is NOT installed by default — `brew install pidof` provides a port, or use the portable `pgrep -x firefox` (works identically on macOS). For one-liner cross-platform: `pgrep -x name || pidof name` falls back from one to the other.
pidof firefoxSame external (Linux only). Idiomatic fish "send signal if process exists": `set p (pidof firefox); and kill -USR1 $p`. The `and` is fish's short-circuit AND — runs only when the previous command succeeded (exit 0).
(Get-Process -Name firefox -ErrorAction SilentlyContinue).IdReturns an Int32 (single PID) or an Int32[] array (multiple). Wildcards: `(Get-Process firefox*).Id`. `-ErrorAction SilentlyContinue` mirrors `pidof`'s "exit silently on no match" behavior — without it, the cmdlet throws on no-such-process. To return JUST the oldest (mirroring `pidof -s`): `Get-Process -Name firefox | Sort-Object StartTime | Select-Object -First 1 -ExpandProperty Id`.
tasklist /FI "IMAGENAME eq firefox.exe" /NH /FO CSVcmd has no direct `pidof` analog. `tasklist /FI "IMAGENAME eq <name>.exe" /NH /FO CSV` produces parsable rows; column 2 is the PID. For a one-line single-PID result: `for /f "tokens=2 delims=," %a in ('tasklist /FI "IMAGENAME eq firefox.exe" /NH /FO CSV') do @echo %~a` (the `%~a` strips the quotes the CSV adds).
Worked examples
Get the PID of a single process
pidof firefox(Get-Process firefox).Idfor /f "tokens=2 delims=," %a in ('tasklist /FI "IMAGENAME eq firefox.exe" /NH /FO CSV') do @echo %~aSend a signal to one named process
kill -HUP $(pidof nginx)Get-Process nginx | ForEach-Object { $_.CloseMainWindow() }Test whether a process is running (exit code)
pidof -q firefox && echo runningif (Get-Process firefox -ErrorAction SilentlyContinue) { "running" }tasklist /FI "IMAGENAME eq firefox.exe" 2>NUL | findstr firefox.exe >NUL && echo runningGotchas
- `pidof` is LINUX-ONLY by default. macOS, FreeBSD, OpenBSD all lack it. The portable substitute is `pgrep -x <name>` (exact match) — works identically on every modern Unix. Scripts that need to run on both Linux and macOS should prefer `pgrep -x`.
- `pidof` matches the LITERAL executable name only — `pidof firefox` matches a process invoked as `/usr/bin/firefox` but NOT one invoked as `python firefox-wrapper.py` (where the COMM is `python`). For interpreter-wrapped processes, `pidof -x` matches the script name; for full-cmdline matching, fall back to `pgrep -f`.
- When MULTIPLE instances are running, `pidof firefox` returns ALL PIDs on one line, separated by spaces — `kill -9 $(pidof firefox)` correctly kills them all. But `kill -9 $(pidof -s firefox)` (with `-s` for single) returns only the OLDEST PID, missing the others. This bites scripts that assume `-s` is "just be deterministic" rather than "intentionally pick one".
- PowerShell `Get-Process firefox` THROWS if no `firefox` is running — unlike `pidof` which exits 1 silently. Always pair with `-ErrorAction SilentlyContinue` for the `pidof`-equivalent behavior, or check via `Get-Process | Where-Object Name -eq firefox` which returns an empty array instead of throwing.
- The cmd `tasklist`-based approach is slow (300–600 ms per invocation) because `tasklist` opens an RPC channel to the Windows session manager. Inside a tight script loop, prefer one `tasklist` call piped through `findstr`/`for` for ALL matches, not one call per name.