What ps Does#
ps takes a snapshot of running processes at the moment you run it. Unlike top or htop which update continuously, ps gives you a static list you can filter, sort, and pipe into other commands.
The Two Syntax Styles#
ps has a long history and accepts two different option styles. Both work — pick whichever you find more readable:
| Style | Example | Origin |
|---|---|---|
| UNIX | ps -ef | System V (options with dash) |
| BSD | ps aux | BSD (options without dash) |
They show similar information in slightly different formats. You’ll see both in documentation and scripts.
Common Options Explained#
UNIX-style options (with dash)#
| Option | Meaning |
|---|---|
-e | Select all processes (every process on the system) |
-f | Full format — shows UID, PID, PPID, start time, TTY, and full command |
-u user | Select processes by username |
-p pid | Select a specific process by PID |
-o fmt | Custom output format (you choose the columns) |
--sort | Sort by a specified field |
--forest | Show process tree with ASCII art |
-f is the most commonly paired option — without it, ps shows a minimal format (just PID, TTY, TIME, CMD). With -f, you get the full picture:
# Minimal output
ps -e
# PID TTY TIME CMD
# 1842 pts/0 00:00:00 bash
# Full format — much more useful
ps -ef
# UID PID PPID C STIME TTY TIME CMD
# mike 1842 1838 0 10:30 pts/0 00:00:00 bashBSD-style options (no dash)#
| Option | Meaning |
|---|---|
a | Show processes from all users (not just yours) |
u | User-oriented format (shows %CPU, %MEM, VSZ, RSS) |
x | Include processes without a controlling terminal (daemons) |
f | Show process tree (forest) |
These combine naturally — aux means “all users + user format + include daemons”:
# Without x — misses background services
ps au
# With x — shows everything including systemd, sshd, etc.
ps auxWhy ps -ef and ps aux show different things#
ps -ef | ps aux | |
|---|---|---|
| Shows PPID | Yes | No |
| Shows %CPU/%MEM | No | Yes |
| Shows VSZ/RSS | No | Yes |
| Full command path | Yes | Yes |
Use ps -ef when you care about process relationships (parent-child). Use ps aux when you care about resource usage.
Common Invocations#
Show all processes (UNIX style)#
ps -efOutput:
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jun21 ? 00:00:03 /usr/lib/systemd/systemd
root 2 0 0 Jun21 ? 00:00:00 [kthreadd]
mike 1842 1838 0 10:30 pts/0 00:00:00 bash
mike 2105 1842 0 10:45 pts/0 00:00:02 vim server.c| Column | Meaning |
|---|---|
UID | User who owns the process |
PID | Process ID |
PPID | Parent process ID |
C | CPU utilization |
STIME | Start time |
TTY | Terminal (or ? for daemons) |
TIME | Total CPU time consumed |
CMD | Command that started the process |
Show all processes (BSD style)#
ps auxOutput:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 169876 13280 ? Ss Jun21 0:03 /usr/lib/systemd/systemd
mike 1842 0.0 0.0 8556 5312 pts/0 Ss 10:30 0:00 bash
mike 2105 0.5 0.2 12456 9876 pts/0 S+ 10:45 0:02 vim server.c| Column | Meaning |
|---|---|
USER | Owner |
PID | Process ID |
%CPU | CPU usage percentage |
%MEM | Memory usage percentage |
VSZ | Virtual memory size (KB) |
RSS | Resident set size — actual RAM used (KB) |
TTY | Terminal |
STAT | Process state |
START | Start time |
TIME | Total CPU time |
COMMAND | Full command |
Just your processes#
ps -fShows only processes owned by you in the current terminal.
Process tree#
ps -ef --forestShows parent-child relationships with indentation:
root 1024 1 /usr/sbin/sshd
root 4521 1024 \_ sshd: mike [priv]
mike 4525 4521 \_ sshd: mike@pts/0
mike 4526 4525 \_ -bash
mike 4600 4526 \_ vim config.cOr with the BSD-style equivalent:
ps auxfProcess States (STAT Column)#
| State | Meaning |
|---|---|
R | Running or runnable |
S | Sleeping (waiting for an event) |
D | Uninterruptible sleep (usually disk I/O) |
T | Stopped (suspended with Ctrl-z) |
Z | Zombie (finished but parent hasn’t collected exit status) |
Additional characters after the state:
| Modifier | Meaning |
|---|---|
s | Session leader |
+ | Foreground process group |
l | Multi-threaded |
< | High priority |
N | Low priority (nice) |
Example: Ss = sleeping session leader, R+ = running in foreground.
Filtering Processes#
By name (with grep)#
ps aux | grep nginxExclude the grep process itself:
ps aux | grep [n]ginxThe bracket trick makes the regex not match itself.
By user#
# UNIX style
ps -u mike -f
# BSD style
ps aux | grep "^mike"By PID#
ps -p 1842 -fBy command name (without grep)#
# Find PIDs by name
pgrep nginx
# With full details
pgrep -a nginx
# Count matching processes
pgrep -c nginxCustom Output with -o#
The -o flag lets you pick exactly which columns to display:
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head -10Output:
PID USER %CPU %MEM COMMAND
3421 mike 12.3 4.5 firefox
2105 mike 0.5 0.2 vim
1 root 0.0 0.1 systemdUseful format specifiers#
| Specifier | Meaning |
|---|---|
pid | Process ID |
ppid | Parent PID |
user | Username |
uid | User ID |
%cpu | CPU percentage |
%mem | Memory percentage |
vsz | Virtual memory (KB) |
rss | Resident memory (KB) |
stat | Process state |
start | Start time |
time | CPU time consumed |
comm | Command name (short) |
args | Full command with arguments |
etime | Elapsed time since start |
nice | Nice value |
tty | Terminal |
Examples#
# Show process name, PID, and elapsed time
ps -eo comm,pid,etime --sort=-etime | head -10
# Show memory hogs
ps -eo pid,user,rss,comm --sort=-rss | head -10
# Show all processes for a user with custom columns
ps -u mike -o pid,ppid,%cpu,%mem,etime,commSorting#
# Sort by CPU usage (descending)
ps aux --sort=-%cpu | head -10
# Sort by memory usage (descending)
ps aux --sort=-%mem | head -10
# Sort by start time (newest first)
ps aux --sort=-start_time | head -10
# Sort by PID
ps -ef --sort=pidThe - prefix means descending. Without it, ascending.
Combining with Other Tools#
Find the top memory consumers#
ps aux --sort=-%mem | head -10Count processes per user#
ps -eo user= | sort | uniq -c | sort -rnFind long-running processes#
ps -eo pid,etime,comm --sort=-etime | head -20Watch a specific process over time#
watch -n 1 'ps -p 2105 -o pid,%cpu,%mem,etime,comm'Find zombie processes#
ps aux | awk '$8 ~ /Z/'Kill all processes matching a name#
# Preview what will be killed
pgrep -a myapp
# Kill them
pkill myappFind which process is using a port#
# First find the PID
ss -tlnp | grep :8080
# Then check what it is
ps -p <PID> -fps vs Other Tools#
| Tool | Best for |
|---|---|
ps | One-time snapshot, scripting, custom output |
top | Real-time monitoring, interactive sorting |
htop | Interactive monitoring with better UI |
pgrep | Finding PIDs by name quickly |
pidstat | Per-process CPU/IO stats over time |
Use ps when you need a scriptable, filterable list. Use top/htop when you’re watching things live.
Practical Scenarios#
“What’s using all my CPU?”#
ps aux --sort=-%cpu | head -5“Is nginx running?”#
pgrep -a nginx
# or
ps aux | grep [n]ginx“What did PID 1 spawn?”#
ps --ppid 1 -f“How long has this process been running?”#
ps -p 2105 -o etime=“Show me everything about one process”#
ps -p 2105 -f
# or for maximum detail
cat /proc/2105/statusBest Practices#
- Use
ps auxorps -efas your default for seeing all processes — pick one style and stick with it - Use
pgrepinstead ofps | grepwhen you just need PIDs — it’s cleaner and doesn’t match itself - Use
-ofor custom output in scripts — it’s more reliable than parsing the default format withawk - Use
--sortinstead of piping tosort— it’s faster and handles column alignment correctly - Remember
psis a snapshot — if you need to catch a short-lived process, usetopor trace tools instead - Check
STATfor zombies (Z) and uninterruptible sleep (D) — these indicate problems worth investigating


