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"
fiGood
if pgrep -x myapp >/dev/null; then
echo "running"
fiExplanation
`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".