How to Find Process by Name in Linux: pgrep, ps, pidof
Find a Linux process by name using pgrep, ps, pidof, and top — with real examples for scripting, killing, and monitoring processes in production.
You know what the process is called. You need its PID, its state, its parent, or just to know if it's running. Here's every reliable way to find a process by name.
TL;DR
pgrep nginx # PID(s) — best for scripting
pgrep -a nginx # PID + full command
ps aux | grep '[n]ginx' # with details, no self-match
pidof nginx # PID only, exact binary name
pgrep: Cleanest for Scripting
pgrep searches the process table by name and returns matching PIDs:
# Basic — returns PID(s)
pgrep nginx
# Show full command line
pgrep -a nginx
# Case-insensitive
pgrep -i NGINX
# Match exact name only
pgrep -x nginx # won't match "nginx-debug"
# By user
pgrep -u www-data nginx
# Count matching processes
pgrep -c nginx
# Return 0 if found, 1 if not — good for conditionals
pgrep -x nginx > /dev/null && echo "running" || echo "not running"
ps: Find with Full Details
ps shows processes with resource usage, state, and parent PID:
# Find all nginx processes
ps aux | grep nginx
# Avoid matching grep itself (important in scripts)
ps aux | grep '[n]ginx'
# The character class [n] doesn't match the string "grep [n]ginx"
# Find by command pattern (full command line)
ps aux | grep "java.*service.jar"
# Show specific columns
ps -eo pid,ppid,user,stat,%cpu,%mem,comm | grep nginx
The self-match problem
# BAD — the grep process shows up in results
ps aux | grep nginx
# nginx 1234 ... nginx: master process
# root 9901 ... grep nginx ← this is the grep itself
# GOOD — character class trick
ps aux | grep '[n]ginx'
# nginx 1234 ... nginx: master process
pidof: Exact Binary Name
pidof matches the exact executable name:
pidof nginx
# 1234 1235 1236 ← master + workers
pidof sshd
# 1023
# Multiple processes
pidof nginx sshd postgres
Unlike pgrep, pidof matches the exact binary name only. pidof ngin returns nothing even though nginx is running.
Finding by Full Command Line
When multiple processes have the same name but different arguments:
# pgrep with full command match
pgrep -f "java.*service-prod.jar"
# ps with grep
ps aux | grep "service-prod.jar" | grep -v grep
# Find all java processes with different configs
ps -eo pid,cmd | grep java | grep -v grep
pgrep -f matches against the full command line including arguments — essential when you have multiple instances of the same binary with different configs.
Real Examples
Check if a service is running
pgrep -x nginx > /dev/null && echo "nginx is running" || echo "nginx is NOT running"
# In a script
if pgrep -x nginx > /dev/null 2>&1; then
echo "OK: nginx running ($(pgrep -c nginx) processes)"
else
echo "ALERT: nginx not found"
exit 1
fi
Find all instances of an app
# List all java processes with their args
ps -eo pid,user,cmd | grep '[j]ava'
# 8823 app java -Xmx4g -jar service-prod.jar
# 9011 app java -Xmx2g -jar worker.jar
Find a process and check its state
PID=$(pgrep -x myapp)
if [ -n "$PID" ]; then
ps -p $PID -o pid,stat,etime,%cpu,%mem,comm
fi
Find and monitor a process's resources
# Watch CPU and memory for nginx
watch -n 2 'ps -eo pid,user,%cpu,%mem,stat,comm | grep [n]ginx'
# Or use top filtered to PID
top -p $(pgrep -d, nginx)
Find zombie processes by name
ps -eo pid,stat,comm | awk '$2 ~ /Z/ && $3 ~ /myapp/'
Output Explanation
ps aux | grep '[n]ginx'
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
www 1234 0.0 0.1 45312 4096 ? Ss 09:15 0:00 nginx: master process /usr/sbin/nginx
www 1235 2.1 0.3 45312 8192 ? S 09:15 1:23 nginx: worker process
www 1236 1.8 0.3 45312 8064 ? S 09:15 1:19 nginx: worker process
Ss— sleeping, session leader (master process)S— sleeping (worker processes)TIME— cumulative CPU time consumed, not wall time
Common Mistakes
Mistake 1: Using ps aux | grep name | awk '{print $2}' | xargs kill
Race condition — PID may change between ps and kill. Use pkill instead:
pkill -TERM nginx
kill $(pgrep -x nginx) # explicit but controlled
Mistake 2: pidof returning nothing for interpreted scripts
pidof python may not find python3 /opt/app/server.py. Use pgrep -f "server.py" instead.
Mistake 3: Not accounting for multiple instances
pgrep nginx returns multiple PIDs. When you only expect one, check:
pgrep -c nginx # count
# If > 1, investigate why
Pro Tips
# Find process and immediately show its open files
lsof -p $(pgrep -x nginx | head -1)
# Find process and trace it
strace -p $(pgrep -x myapp)
# Find processes started in the last 5 minutes
ps -eo pid,lstart,cmd | awk -v d="$(date -d '5 minutes ago' '+%s')" '
NR>1 && mktime($2" "$3" "$4" "$5" "$6) > d {print}'
# Find by port (combine ss + pgrep)
PID=$(ss -tlnp | awk -F'pid=' '/8080/{print $2}' | cut -d, -f1)
pgrep -a -P $PID # show children of that PID
Conclusion
pgrep is the right tool for scripting — returns clean PIDs, supports exact matching, works with full command line via -f. ps aux | grep '[name]' is for interactive investigation where you want context. pidof is fast when you know the exact binary name. Never use ps | grep | awk | kill pipelines in scripts — use pkill or kill $(pgrep ...) instead.
Related: ps Command Linux: The Engineer's Troubleshooting Guide — full ps usage for production investigation. Linux Kill Process by Port — when you need to find and kill by port instead of name.