Skip to content

Inspecting Processes with ps


You’ve used ps a few times already in this section as a quick preview tool, always with a -o flag telling it exactly what to show. That was deliberate — ps on its own is one of the most inconsistent, historically tangled commands in this entire course, and it deserves a proper explanation before you’re relying on it against a real, busy system.

Why ps Feels Confusing At First

ps predates a lot of the conventions covered back in the Terminal & Shell Basics chapter. It supports two different flag styles simultaneously — traditional UNIX-style single-dash flags and BSD-style flags with no dash at all — and they don’t always mean the same thing, don’t always combine cleanly, and both remain in extremely common use. This isn’t a quirk you can avoid by picking “the right way” — you’ll see both styles constantly in documentation, forums, and other people’s scripts, so both are worth actually knowing.

The Two Everyday Forms

ps aux — BSD-style, no leading dash:

ps aux
  • a — show processes for all users, not just the current one
  • u — display in a user-oriented format, with useful columns like CPU and memory usage
  • x — include processes not attached to a terminal (background services, daemons)

ps -ef — UNIX-style, with a leading dash:

ps -ef
  • -e — show every process on the system
  • -f — full-format listing, including parent PID and full command line

Both commands aim at roughly the same goal — “show me everything running, with useful detail” — but produce different columns and slightly different scopes. ps aux is generally considered more informative for resource usage at a glance (it includes CPU and memory percentages directly); ps -ef is often preferred when the parent-child relationship matters, since PPID is front and center. Neither is strictly “correct” — you’ll develop a preference, but recognize both on sight regardless of which one you personally reach for.

Reading The Columns

A ps aux line looks like this:

USER   PID  %CPU  %MEM   VSZ    RSS  TTY   STAT  START  TIME   COMMAND
you    2044  0.3   1.2  21344  9876  pts/0  S    09:14  0:02   bash
ColumnMeaning
USERWho owns this process
PIDThe process ID, from the last two files
%CPUPercentage of CPU currently being used
%MEMPercentage of physical memory currently being used
VSZVirtual memory size — total memory the process has claimed, including memory it isn’t actively using
RSSResident Set Size — memory actually held in physical RAM right now, generally the more meaningful number of the two
TTYThe terminal this process is attached to, or ? if it has none (typical of background services)
STATThe process state letters from the What Is A Process chapter — S, R, D, T, Z
STARTWhen the process began
TIMETotal CPU time consumed so far — not wall-clock time, actual processor time
COMMANDThe command that launched it

Tip

VSZ vs. RSS is a common point of confusion. VSZ includes memory a process has reserved but might never actually touch, and can look alarmingly large for processes that are, in practice, using very little real memory. RSS is the number that actually reflects current physical memory pressure on the system — when you’re hunting for what’s actually consuming RAM, RSS is almost always the column worth trusting.

Choosing Exactly What You Want: -o

Both ps aux and ps -ef give you a fixed, predetermined set of columns. -o lets you specify exactly which columns you want, in whatever order you want them — this is the form you’ve already seen briefly in the last two files.

ps -o pid,ppid,user,%cpu,%mem,stat,cmd

This prints only the columns you asked for, nothing else. For a system with a lot of running processes, this is often more useful than either default format — you’re not scanning past a dozen columns you don’t care about to find the two or three you’re actually investigating.

Sorting Output: Finding What’s Actually Expensive

By default, ps output isn’t sorted by anything particularly useful. --sort fixes that, and it’s one of the most practically important flags in this entire chapter:

ps aux --sort=-%cpu

The leading - before %cpu means descending order — highest CPU usage first. This is very often the very first command you’d run when a system feels sluggish: instantly see what’s actually consuming the CPU, instead of scanning a long unsorted list by eye.

ps aux --sort=-%mem

Same idea, sorted by memory usage instead — the equivalent first move when a system is running low on RAM rather than CPU.

Combining -o And --sort For A Real Diagnostic View

Put both together and you get something genuinely practical — a short, sorted, relevant view instead of a wall of every process on the system:

ps -eo pid,user,%cpu,%mem,cmd --sort=-%cpu | head

This lists every process (-e), with exactly the columns that matter for a quick health check, sorted by CPU usage descending, piped into head (from the Viewing Files chapter) to show just the top handful — the processes actually worth paying attention to, front and center, with everything else cut away.

Looking At One Specific Process

If you already know a PID — say, from the output above, or from a tool covered later in this section — -p narrows ps down to just that process:

ps -o pid,ppid,stat,%cpu,%mem,cmd -p 2044

Useful for re-checking a specific process’s state after you’ve already identified it, without the noise of everything else running.

What ps Is — And Isn’t — Good At

ps gives you a snapshot: the state of every process at the exact moment you ran the command, and nothing after that. It doesn’t refresh, it doesn’t show trends, and running it twice in a row against a fast-changing system can show meaningfully different numbers each time, with no indication of why they changed.

That’s precisely the gap top, later in this section, exists to fill — a live, continuously updating view instead of a single frozen moment. ps is what you reach for when you want a precise, scriptable, one-time answer; top is what you reach for when you want to watch a system’s behavior unfold over time.

What’s Next

You can now read, filter, and sort a full process listing confidently. What ps still can’t do cleanly on its own is answer a very specific, very common question: “is a process matching this name or pattern currently running?” Piping ps into grep to answer that seems obvious — and it’s a genuine trap, which is exactly what the next chapter is about.

Last updated on