Skip to content
shellmap

pgrepFind PIDs of running processes by name — the lookup half of pkill across all 5 shells

Equivalents in every shell

Bashunix
pgrep firefox

Companion to `pkill`. Prints one PID per line — perfect for `for pid in $(pgrep firefox); do ...`. `-a` adds the command line beside the PID; `-l` adds just the process name; `-f` matches the full command line (same as `pkill -f`); `-d ,` joins PIDs with commas — handy for `kill -9 $(pgrep -d , firefox)`.

Zshunix
pgrep firefox

Same external. macOS BSD `pgrep` is mostly compatible — `-a` (cmdline) and `-l` (name) both work; `-d` (delimiter) is supported. `-c` (count only) is the same on both. For the oldest of cross-platform scripts, the lowest-common-denominator is `pgrep -f "<pattern>"` without `-a` or `-l`.

Fishunix
pgrep firefox

Same external. Fish-specific idiom for "kill if running": `set pid (pgrep firefox); and kill $pid`. Avoid `$(pgrep ...)` — fish prefers `(pgrep ...)` for command substitution. Exit status: 0 if ≥1 match, 1 if no match, 2 on error.

PowerShellwindows
Get-Process -Name firefox

No wildcard-supporting `pgrep` analog ships as a cmdlet, but `Get-Process` is the canonical equivalent. Wildcards: `Get-Process firefox*`. Full-cmdline grep: `Get-CimInstance Win32_Process -Filter "CommandLine LIKE '%pattern%'" | Select-Object ProcessId, CommandLine`. For JSON: `Get-Process firefox | Select Id, ProcessName | ConvertTo-Json`.

cmd.exewindows
tasklist /FI "IMAGENAME eq firefox.exe"

`/FI` accepts the filter format `<column> <op> <value>`. Columns: `IMAGENAME`, `PID`, `STATUS`, `USERNAME`, `WINDOWTITLE`, `MEMUSAGE`. Operators: `eq`, `ne`, `gt`, `ge`, `lt`, `le`. To get JUST the PIDs: `tasklist /FI "IMAGENAME eq firefox.exe" /FO CSV /NH` then strip-and-parse the CSV.

Worked examples

List PIDs matching a name

Bash
pgrep firefox
PowerShell
(Get-Process firefox).Id
cmd.exe
tasklist /FI "IMAGENAME eq firefox.exe" /FO CSV /NH

Show PID + command line for matches

Bash
pgrep -a firefox
PowerShell
Get-CimInstance Win32_Process | Where-Object Name -eq firefox.exe | Select ProcessId, CommandLine
cmd.exe
wmic process where "name='firefox.exe'" get processid,commandline

Test if a process is running (boolean exit code)

Bash
pgrep -q firefox && echo "running"
PowerShell
if (Get-Process firefox -ErrorAction SilentlyContinue) { "running" }
cmd.exe
tasklist /FI "IMAGENAME eq firefox.exe" | findstr /I firefox.exe

Gotchas

  • Same 15-char COMM truncation issue as `pkill` on Linux. `pgrep chromium-browser` returns nothing; `pgrep -x chromium-browse` works; `pgrep -f chromium-browser` is the most reliable. The truncation is a kernel-level limit on `/proc/<pid>/comm`, not a `pgrep` bug.
  • `pgrep` without flags matches as a SUBSTRING regex — `pgrep node` matches both `node` and `nodemon`. To require an exact word match: `pgrep -x node`. To match an anchored regex: `pgrep "^node$"` (works because the argument is treated as a regex by default).
  • PowerShell `Get-Process -Name foo` THROWS a terminating error if no processes match — unlike `pgrep` which returns exit 1 silently. Always pair with `-ErrorAction SilentlyContinue` in scripts: `Get-Process firefox -ErrorAction SilentlyContinue`. Or check via `Get-Process | Where-Object Name -eq firefox` which returns empty array on no match.
  • On Windows, `tasklist` requires the `.exe` suffix in `IMAGENAME` filters. `tasklist /FI "IMAGENAME eq firefox"` returns NOTHING; `tasklist /FI "IMAGENAME eq firefox.exe"` works. PowerShell `Get-Process firefox` (no `.exe`) is the consistent cross-platform spelling.
  • Both `pgrep -f` and `Win32_Process.CommandLine` lookups can race with very short-lived processes — a script that does `pgrep firefox && pkill firefox` may see the process between the two calls. For atomicity, `pkill firefox` itself (or `Stop-Process -Name firefox`) does the lookup and kill in one syscall flow.

WSL & PowerShell Core notes

pwsh`Get-Process` is the cross-platform pwsh equivalent — same on Windows/Linux/macOS pwsh. Properties differ: Windows pwsh `Get-Process` exposes `MainWindowTitle`, `Modules`, `Path`; Linux/macOS pwsh `Get-Process` does NOT expose `MainWindowTitle` (no GUI subsystem), and `Path` requires permission to read `/proc/<pid>/exe`. For full-cmdline grep on Linux pwsh: `Get-Process | Where-Object { (Get-Content "/proc/$($_.Id)/cmdline" -Raw -ErrorAction SilentlyContinue) -match "pattern" }`.
WSLInside WSL `pgrep` lists Linux-side processes only. To list Windows-side: `tasklist.exe /FI "IMAGENAME eq notepad.exe"` (or just `tasklist.exe` for everything). The two namespaces are completely separate — there is no `pgrep` that spans both. For a unified view, query each side and join in jq / pwsh.

Common tasks using pgrep

Related commands