Home / Alt manpages / pgrep(1)

  • pgrep(1)
  • User command
  • linux

Find the right process before you signal it with pgrep

You will finish with a repeatable way to find processes, narrow the match to the right user or command line, and decide whether to inspect, signal or wait. The installed command is procps-ng 4.0.4 from the Ubuntu procps package version 2:4.0.4-4ubuntu3.3. Allow about 15 minutes. You need a shell; the read-only examples need no elevated privileges.

pgrep prints process IDs that match a pattern. The same program also provides pkill, which sends a signal, and pidwait, which waits for matching processes. Treat matching as a selection problem first. A command that finds one process in a test shell can find several processes on a busy host.

1. Check the installed version

Start by confirming which implementation and version you are using:

$ pgrep --version
pgrep from procps-ng 4.0.4

The manual page installed with this version is dated 16 January 2023. Options and details below describe that local implementation, not every similarly named tool on another operating system.

2. Match a process name exactly

With no extra selector, the pattern is an extended regular expression matched against the process name. Use -x when you mean one complete name, rather than a substring:

$ pgrep -x sshd
1842
1910

Your PIDs will differ. If there is no output, no process matched and the command exits with status 1. A successful match exits 0. Check the status immediately when scripting or diagnosing a surprising result:

$ pgrep -c -x sshd
2
$ printf '%s\n' "$?"
0

-c prints a count instead of the PIDs. A zero count is still a non-zero result, so do not treat the printed number as the only signal from the command.

3. Inspect the name and full command line

The kernel process name used by the normal match is limited to 15 characters. That can make two commands look alike. Add -l to show the name beside each PID, or -a to show the complete command line:

$ pgrep -a -x python3
1176 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal

Use -f when the pattern itself must be matched against the full command line. Combine it with -x only when the entire command line is known exactly. Otherwise, prefer a distinctive fragment and inspect the result before taking action:

$ pgrep -af 'unattended-upgrade-shutdown'
1176 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal

The pattern is a regular expression. Characters such as ., [ and * have regular-expression meanings. Quote a pattern containing shell metacharacters so the shell does not reinterpret it first. If you want literal matching by name, -x is usually easier to review than a complicated expression.

4. Add selectors instead of guessing from names

Selection options are cumulative: separate criteria must all match. Comma-separated values within one option mean any of those values. For example, this finds sshd processes whose effective user is either root or daemon:

$ pgrep -a -u root,daemon -x sshd
1842 /usr/sbin/sshd -D
1910 sshd: user@pts/0

Useful selectors include -u for effective user ID, -U for real user ID, -P for parent PID, -g for process group, -s for session, -t for controlling terminal and -r for process state. Numeric IDs are often less ambiguous in scripts:

$ pgrep -a -P 1842
1910 sshd: user@pts/0

If you are checking a process started by a wrapper or privilege escalation tool, -A excludes the ancestors of pgrep, pkill or pidwait. This can prevent the inspection command itself from contributing an unexpected match.

5. Choose one process when several match

-n selects the newest matching process, while -o selects the oldest. -O SECONDS selects processes older than a given age. These options cannot be combined with one another in every combination: the local manual specifically says -n, -o and -v cannot be combined.

$ pgrep -a -n -x sshd
1910 sshd: user@pts/0
$ pgrep -c -O 3600 -x sshd
1

Do not infer that the first PID printed is the oldest or newest. Use the selector explicitly. The -O check can silently fail when /proc is mounted with the subset=pid option, so investigate the host's proc mount if age filtering behaves unexpectedly.

6. Use pkill only after reviewing the exact match

Warning

pkill changes process state. Its default signal is SIGTERM, and a broad match can stop a service, log out users or terminate the wrong workload. First run the equivalent pgrep command with -a, then copy the selectors into pkill. Do not add sudo merely because it is familiar; use elevated privileges only when the target process and your operational procedure require them.

$ pgrep -a -u appuser -x example-worker
2487 /usr/local/bin/example-worker --config /etc/example-worker.conf
$ pkill -TERM -u appuser -x example-worker

The example sends a normal termination request to every matching worker owned by appuser. It does not guarantee that the process exits immediately. Verify the result without signalling anything else:

$ pgrep -a -u appuser -x example-worker
$ printf '%s\n' "$?"
1

For a daemon with a documented reload signal, specify it explicitly, such as pkill -HUP -x example-daemon, and confirm the service's own documentation before doing so. There is no universal undo for a terminated process. Recovery means restarting it through the service manager or restoring the workload using its normal operational procedure.

7. Wait for matching processes when that is the real goal

pidwait uses the same matching rules but waits for each matched process instead of listing or signalling it. This is useful after starting a child process when you want to wait by a carefully chosen identity. The command requires the Linux pidfd_open system call, available since Linux 5.3:

$ pidwait -P "$PPID" -x example-worker
$ printf '%s\n' "$?"
0

Use a parent or user selector that cannot accidentally include unrelated jobs. On systems without the required kernel call, pidwait cannot provide this behaviour. For a single known child PID, the shell's wait builtin may be clearer because it also returns that child's exit status.

8. Check the result and stop before acting

Remember the exit statuses: 0 means at least one process matched, and for pkill or pidwait at least one process was successfully signalled or waited for; 1 means no match or no successful action; 2 is a command-line syntax error; 3 is a fatal error such as running out of memory. A non-zero result is not a reason to retry with a broader pattern.

Checkpoint: before every signal, run the read-only form with -a and confirm the PID, owner and command line. If the output is empty, pause and investigate the name, regular expression, user, namespace or timing. The running pgrep, pkill or pidwait command does not report itself as a match, but that does not make an otherwise broad pattern safe.

Done means

  • You confirmed the local procps-ng version.
  • You used -x, -f or a selector such as -u or -P to make the match precise.
  • You inspected pgrep -a output before considering pkill.
  • You checked the command's exit status and understood what an empty match means.
  • You have a service-specific recovery path before sending a signal that changes state.