ps aux
The one most people type. BSD syntax, no leading dash: means other users' processes, adds the user-oriented columns, adds processes with no controlling terminal (daemons).
| Command | What it does |
|---|---|
| Every process on the machine, user-oriented format | |
| Same, one page at a time | |
| Same, with full command lines instead of truncated ones | |
| Only your own processes | |
| Every process, short format (no user or memory columns) | |
| Pick your own columns, BSD style | |
| Only processes attached to the current terminal | |
| The ten biggest memory users | |
| The usual way people filter it (see grep) | |
| Every process as a tree, with PPID and process group |
ps -ef
UNIX syntax, single dash: selects every process and is the full-format listing. It is the same process list as with a different set of columns, and it is the form you will see in older scripts and on AIX, Solaris and HP-UX.
| Command | What it does |
|---|---|
| Every process, full format | |
| Filter it ( is cleaner) | |
| Extra full: adds RSS, physical memory and the CPU it last ran on | |
| Long format: priority, nice value, wait channel, state | |
| Long format with RSS instead of address fields | |
| Every process, PID and command only | |
| Full command lines, no truncation at terminal width | |
| Full format drawn as a tree | |
| Same idea, your own columns |
Flag Styles
ps accepts three different option syntaxes, and this is the single most confusing thing about it. All three work at once, which is why and both look correct and both are.
| Style | Looks like | Notes |
|---|---|---|
| BSD | No dash. Letters stack: , , , , , | |
| UNIX / POSIX | One dash. , , , , , , | |
| GNU long | Two dashes. , , , , |
The same letter can mean different things in different styles, so the dash is not decoration:
| Pair | Difference |
|---|---|
| vs | BSD is an output format; UNIX takes a username |
| vs | Real user (who owns it) vs effective user (whose rights it runs with) |
| vs | BSD: drop the terminal requirement. UNIX is not a select option at all |
| vs | asks for the processes of a user named ; procps prints a warning and usually falls back |
| vs | Full-format columns vs the BSD forest (tree) drawing |
Mixing a BSD option and a UNIX option in one command is where comes from. Pick one style per command.
Output Columns
What prints, left to right:
| Column | Meaning |
|---|---|
| The user the process runs as | |
| Process ID, the number you pass to | |
| CPU time used divided by how long the process has been alive, so it is a lifetime average, not what it is doing this second | |
| RSS as a percentage of physical RAM | |
| Virtual size in KB: everything mapped, including libraries and untouched reservations. Usually alarming and usually meaningless | |
| Resident set size in KB: real RAM in use now. This is the number that matters | |
| Controlling terminal. means none, which is normal for daemons; is an SSH session | |
| Process state plus modifiers (see below) | |
| When it started. A clock time for today, a date for anything older | |
| Total CPU time consumed, not wall-clock age | |
| The command line, truncated to the terminal width unless you pass |
prints a different set:
| Column | Meaning |
|---|---|
| Owner, shown as a name when it fits | |
| / | The process and its parent. Follow PPID up to find what started it |
| Integer CPU utilisation, a rounded and mostly obsolete version of | |
| Start time, same idea as | |
| Controlling terminal | |
| Cumulative CPU time | |
| The command line |
A process with a command in square brackets, such as , is a kernel thread, not a program you installed.
STAT Codes
The first letter is the state. Anything after it is a modifier.
| Code | Meaning |
|---|---|
| Running, or sitting on the run queue ready to run | |
| Interruptible sleep, waiting for something. Most processes, most of the time | |
| Uninterruptible sleep, almost always disk or NFS I/O. Cannot be killed, not even with | |
| Stopped by a job control signal (Ctrl+Z, or ) | |
| Stopped by a debugger | |
| Zombie: finished, but the parent has not read its exit status | |
| Idle kernel thread | |
| High priority (negative nice) | |
| Low priority (positive nice) | |
| Has pages locked into memory | |
| Session leader | |
| Multi-threaded | |
| In the foreground process group |
So is a sleeping, multi-threaded session leader, which is what a healthy daemon looks like. and a long run of are the two worth chasing.
Filter by User
| Command | What it does |
|---|---|
| Processes running with that effective user | |
| Same, full format | |
| Real and effective user, BSD columns | |
| Several users at once, comma separated | |
| Your own processes with elapsed time | |
| By numeric UID | |
| Count processes per user | |
| Everything except root's processes ( negates the selection) |
Filter by PID
| Command | What it does |
|---|---|
| One process by PID | |
| Same, with PPID and the full command | |
| Several PIDs, chosen columns | |
| Just the command line, no header | |
| How long it has been running, formatted and in seconds | |
| The children of a process | |
| Everything reparented to init or systemd | |
| Every PID of a named process | |
| Just the parent PID, handy in scripts |
gives the same command line when ps is not installed.
Find by Name
| Command | What it does |
|---|---|
| PIDs and command lines for a name (no grep, no self-match) | |
| Match against the whole command line, not just the binary name | |
| Everything one user runs | |
| Select by exact command name, ps's own version of the same thing | |
| Exact name, with columns | |
| PIDs only, ready to pipe into | |
| The bracket trick, so grep does not match itself | |
| Kill by pattern ( first to check what it matches) | |
| All PIDs of a binary on one line |
For a service you manage with systemd, shows the same PIDs plus the unit state and recent logs. See systemctl and journalctl.
Sort by Memory and CPU
takes a column key. A leading sorts descending, or nothing sorts ascending.
| Command | What it does |
|---|---|
| Top ten memory users (line 1 is the header) | |
| Top ten by lifetime average CPU | |
| Same by real RSS, in a tighter format | |
| The longest-running processes | |
| The most recently started | |
| Two keys, in order |
# Memory used per program name, biggest first
ps -eo comm,rss --no-headers | awk '{m[$1]+=$2} END {for (c in m) printf "%8.1f MB %s\n", m[c]/1024, c}' | sort -rn | headRemember that in ps is an average over the life of the process. A process that pinned a core for an hour last night still ranks high, and one spiking right now may not. For live CPU, use top or htop.
Custom Format
(or for every process) replaces the default columns with exactly the ones you ask for.
| Command | What it does |
|---|---|
| A practical default | |
| Binary name only (15 chars max) | |
| The full command line with arguments | |
| What a stuck process is waiting on | |
| Exact start date and time, not the abbreviated | |
| Nice value and priority | |
| Drop the header row, for scripts | |
| Widen one column to 120 characters | |
| Rename headers with | |
| One value, no header, ready for a variable | |
| The four user identities of a process |
Common keys: , , , , , , , , , , , , , , , , , , , , , . prints the whole list.
Threads
| Command | What it does |
|---|---|
| Every thread on the machine, with (thread ID) and (thread count) | |
| The threads of one process | |
| How many threads it has, as a bare number | |
| The busiest threads | |
| Threads with an column | |
| Scheduling class and realtime priority per thread |
A thread's or is the number and show when you turn threads on, so you can match one to the other.
Process Tree
| Command | What it does |
|---|---|
| Full listing drawn as a tree | |
| BSD version, with PPID, PGID and session | |
| One user's processes as a tree | |
| Tree with your own columns | |
| Hierarchy by indentation instead of line drawing | |
| The dedicated tool, with PIDs | |
| The ancestry of one PID, up to init |
ps vs top
| Question | / | |
|---|---|---|
| What it gives you | One snapshot, then exits | A live view that refreshes |
| means | Average over the whole life of the process | Usage during the last refresh interval |
| Scripting | Built for it: , , exact fields | Needs and parsing |
| Sorting | on any column | Interactive keys, or in top |
| Killing a process | Read the PID, then | Press (top) or (htop) |
| Best for | Finding a PID, scripts, an exact column set | Watching load as it happens |
Rule of thumb: answers "what is running and what is its PID", answers "what is eating the machine right now". Full keys and columns are on the top and htop sheet.
Gotchas
- and are both right. is not: it asks for a user named , and only works because procps guesses what you meant and warns you.
- Mixing styles in one command gives . is fine because GNU long options combine with either style, but is not.
- is a lifetime average. Sorting by it finds yesterday's hog, not today's.
- Summing the column overcounts, because shared libraries are charged in full to every process that maps them.
- A state process ignores every signal including . It is stuck in the kernel, usually on disk or NFS, and only unblocks when the I/O finishes or the machine reboots.
- Output is truncated to terminal width. Add (, ) before deciding a command line looks wrong.
- always matches its own grep. Use or .
- is a different command with different flags. It lists containers, not processes; is the one that lists processes inside a container. See the docker sheet.
- A minimal container image has no at all. Install , or run from the host.
- To find which process owns a port, ps is the wrong tool. Use or , covered on the netstat and ss sheet.