>_cmd.script

ps

Show a snapshot of currently running processes

Processes

By CMD Script Team · 4 min read · Last updated

SYNTAX
ps [OPTIONS]

Options

Command options and flags
FlagDescription
-eShow every process on the system, not just the current user/session
-fFull-format listing: shows UID, PPID, start time, and full command line
auxBSD-style flags: all processes (a), for all users including no-tty (u is user-oriented format, x includes processes without a controlling terminal)
-pShow only the specified PID(s), e.g. -p 1234,5678
-uShow only processes owned by a given user, e.g. -u alice
--sortSort output by a field, e.g. --sort=-%cpu for descending CPU usage
-oCustomize output columns, e.g. -o pid,ppid,cmd,%cpu,%mem

Distribution compatibility

  • Ubuntu
  • Debian
  • Fedora
  • Arch
  • macOS (BSD ps, aux syntax works, -ef differs slightly)

What it does

ps prints a snapshot of currently running processes — unlike top/htop, it doesn't refresh live; it just reports what's running at the moment you run it, which makes it ideal for scripting and one-off checks. Its output format and default scope depend heavily on which option "dialect" you use: plain ps shows only processes tied to your current terminal, while -ef or aux broaden it to every process on the system, just in two historically different (System V vs BSD) column layouts.

Beginner examples

  • ps — list processes attached to your current terminal session only
  • ps -ef — list every process on the system in full format (UID, PID, PPID, start time, CMD)
  • ps aux — list every process, BSD style, including ones without a controlling terminal
  • ps aux | grep nginx — find all processes matching "nginx"
ps aux | grep nginx

Advanced examples

  • Sort all processes by memory usage, descending: ps aux --sort=-%mem | head
  • Sort by CPU usage instead: ps aux --sort=-%cpu | head
  • Get exactly the columns you want in a script-friendly format: ps -eo pid,ppid,user,%cpu,%mem,cmd --sort=-%cpu
  • Show the full process tree with parent/child indentation: ps -ef --forest
  • Check on specific PIDs only: ps -p 1234,5678 -o pid,cmd,%cpu,%mem
ps -eo pid,ppid,user,%cpu,%mem,cmd --sort=-%cpu | head -10

Common mistakes

  • Using plain ps and expecting to see all system processes — it only shows processes tied to the invoking shell's session unless you add -e/aux.
  • Piping into grep and forgetting grep itself briefly appears in the process list with the search term in its own command line; use pgrep or the bracket trick (grep '[n]ginx') to avoid the extra match.
  • Mixing BSD-style flags without a leading dash (ps aux) with UNIX-style flags that need one (ps -ef) inconsistently — both work, but combining them incorrectly (e.g. ps -aux) produces a warning on Linux because -a is being parsed as a UNIX-style flag.
  • Assuming %CPU/%MEM in ps output is a live, current value — it's computed at the moment ps runs, a single sample, not an average over time like top's refreshing view.

Tips

  • Use pgrep <name> instead of ps aux | grep <name> when you just need matching PIDs — it's simpler, avoids the self-match issue, and is easier to use in scripts.
  • Customize columns with -o to get exactly the fields you need for a script: ps -o pid=,cmd= prints bare PID and command with no header, easy to parse.
  • Add --forest to ps -ef or ps -eo pid,ppid,cmd to visualize process hierarchy with ASCII tree indentation, similar to htop's tree view.
  • Combine with xargs for bulk actions, e.g. ps -eo pid,cmd | grep defunct | awk '{print $1}' | xargs -r kill -9 to clean up zombie/defunct processes.

Best practices

  • Prefer ps -eo ... with explicit custom columns in scripts over parsing aux/-ef output positionally — column widths and content can vary slightly across distributions.
  • Use pgrep/pkill instead of ps | grep | awk | kill chains when the goal is simply "find/signal processes by name" — it's more robust and less code.
  • When debugging live resource usage over time, use top/htop instead of repeated ps calls — ps is a snapshot, not a monitoring tool.
  • Always double check PIDs from ps output before killing, especially when scripting — PIDs get reused quickly on busy systems and stale PID files can point at the wrong process.

Try it yourself

A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.

Real-world use cases

  • Writing a health-check script that verifies a specific daemon is running: ps -C nginx -o pid= | grep -q . && echo running.
  • Investigating a memory leak by taking periodic ps aux --sort=-%mem snapshots and watching one process's %MEM climb over time.
  • Auditing what's running under a particular user account before decommissioning it: ps -u olduser -o pid,cmd.

Common interview questions

  • What's the difference between ps -ef and ps aux? Both show all processes system- wide, but -ef uses UNIX/System V-style columns (UID, PID, PPID, C, STIME, TTY, TIME, CMD) while aux uses BSD-style columns (USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND) and also includes processes without a controlling terminal.
  • How would you find a process's PID by name without ps matching its own grep call? Use pgrep <name>, which is purpose-built for this and doesn't suffer from the self-matching issue that ps aux | grep <name> has.
  • Is ps output a live view like top? No — ps takes a single snapshot at the moment it runs and exits; for continuously refreshing views you'd use top, htop, or watch ps ....

Frequently Asked Questions

What's the difference between ps, ps -ef, and ps aux?

Plain ps with no options shows only processes attached to your current terminal session. ps -ef (UNIX/System V style) shows every process on the system in full format. ps aux (BSD style) also shows every process, including those without a controlling terminal, but with a different column layout — both -ef and aux are commonly used to see 'everything', just in different formats.

How do I find the PID of a specific running program?

Pipe ps into grep, e.g. ps aux | grep nginx, or use the more direct pgrep nginx which is built for exactly this and avoids the classic 'grep matching its own grep process' gotcha.

Why does grepping ps output sometimes show an extra line for grep itself?

Because grep's own process temporarily shows up in the process list with the search term in its command line (e.g. grep nginx). Avoid it with ps aux | grep '[n]ginx' (bracket trick) or just use pgrep nginx instead.

How do I sort ps output by memory or CPU usage?

Use ps aux --sort=-%mem for descending memory usage, or ps aux --sort=-%cpu for descending CPU usage.

Cheat sheet

Download a quick-reference cheat sheet for ps.