Use pgrep instead of grepping ps output

Parsing `ps | grep` is racy and matches the grep itself. `pgrep` exists for exactly this.

Problem

`ps aux | grep myapp` has two well-known bugs: the grep process itself shows up in the listing, and `ps` output is not stable across platforms. People wrap it with `grep -v grep` or `[m]yapp` tricks; both are fragile.

Bad

if ps aux | grep -v grep | grep -q myapp; then
  echo "running"
fi

Good

if pgrep -x myapp >/dev/null; then
  echo "running"
fi

Explanation

`pgrep -x` matches the exact process name; `pgrep -f` matches the full command line. Both skip themselves automatically and return a non-zero exit code when nothing matches, which composes well with `if`.

When It Matters

ps aux | grep name matches the grep process itself, so the pipeline almost always finds one result even when the target is not running. Scripts work around it with grep -v grep, which then breaks whenever a legitimate process has "grep" in its command line. ps output is also truncated and reformatted differently across systems, so parsing it for a PID is fragile: column positions shift, long command lines are cut off, and the header line has to be skipped.

Second Example

Note

pgrep -x matches the process name exactly; without -x a search for "ssh" also matches "sshd" and any script with ssh in its name.

Exceptions

pgrep is not POSIX and is missing from some minimal busybox images, so a ps pipeline is a legitimate fallback there. Make it exact rather than approximate: match on a full path or use the daemon’s own pidfile, which is more reliable than either approach.

Faq

Q

Why does grep -v grep sometimes still fail?

A

It filters out lines containing "grep", which also removes real processes whose command line mentions grep, and it does nothing about race conditions where the grep process appears under a different name.

Q

Is there something better than pgrep for services?

A

Yes. If the process is managed by systemd, systemctl is-active name answers definitively and accounts for restarts and failed states.

Q

How do I match the whole command line?

A

pgrep -f matches against the full argument list rather than just the executable name, which is what you need for interpreted scripts run as "python worker.py".