ps options and reading its output
Every column BusyBox ps can show, what the STAT letters mean, and how to filter, sort and count processes by piping ps into the text tools.
What you will learn
- Choose any of the twelve `-o` columns and know what each one measures.
- Decode the STAT field: R, S, D, T, Z and the flags W, <, N.
- Combine `ps` with `grep`, `sort`, `wc` and `awk`, avoiding the grep-finds-itself trap.
One option, twelve columns
On a full distribution ps is famous for having three incompatible option styles: ps aux, ps -ef, ps --forest. BusyBox keeps exactly one: -o followed by a comma-separated list of columns. Type ps aux here and BusyBox silently ignores the letters and prints the default view, which can mislead you into thinking the options worked. The supported columns are pid, ppid, pgid, sid, user, group, comm, args, stat, tty, vsz and rss; ask for anything else and ps lists that set in its error message.
| Column | Meaning |
|---|---|
pid, ppid | Process id and parent's id |
pgid, sid | Process group (a pipeline shares one) and session (a terminal login) |
user, group | Effective owner and group |
comm | Short program name, 15 characters max |
args | Full command line as typed |
stat | State letters, see below |
tty | Controlling terminal, ? for none |
vsz, rss | Virtual size and resident memory, in KiB |
~% ps -o pid,ppid,stat,tty,vsz,rss,args
PID PPID STAT TT VSZ RSS COMMAND
1 0 S ? 1352 188 init
2 0 SW ? 0 0 [kthreadd]
4 2 IW< ? 0 0 [kworker/0:0H]
859 1 S ttyS0 1356 220 -/bin/sh
1011 859 S ttyS0 1340 160 sleep 1000
1015 859 R+ ttyS0 1352 180 ps -o pid,ppid,stat,tty,vsz,rss,args
Reading STAT
| Letter | State | Typical cause |
|---|---|---|
R | Running or ready to run | Using the CPU right now (ps always shows itself as R) |
S | Sleeping, interruptible | Waiting for input, a timer, a child: the normal idle state |
D | Uninterruptible sleep | Waiting on disk or network I/O; cannot be killed until it returns |
T | Stopped | Ctrl-Z or SIGSTOP; resumes with fg, bg or SIGCONT |
Z | Zombie | Exited, but the parent has not collected its exit status yet |
I | Idle kernel thread | Only on kernel workers |
W < N + | Flags | No resident pages (kernel thread), high priority, low priority (niced), foreground process group |
Most of a healthy system is S. A process stuck in D for a long time points at a hung disk or network mount. A Z costs nothing but a PID; it goes away when its parent calls wait, or when the parent dies and init adopts it. You cannot kill a zombie, it is already dead.
ps is just text: pipe it
~% ps -o pid,args | grep sleep
1011 sleep 1000
1020 grep sleep
~% ps -o pid,args | grep '[s]leep'
1011 sleep 1000
~% ps | wc -l
50
~% ps -o comm | sort | uniq -c | sort -rn | head -3
4 init
3 sh
2 sort
~% ps -o pid,rss,args | sort -k2 -n | tail -2
The first command shows the classic trap: grep sleep matches *its own* command line, because grep sleep was running when ps took the snapshot. The bracket trick, '[s]leep', is a regular expression that matches the word sleep but does not appear literally in the grep command line, so grep no longer finds itself. From there, the rest of the toolbox applies: wc -l counts (minus one for the header), sort | uniq -c tallies program names, sort -k2 -n orders by memory.
Commands in this lesson
| Command | What it does |
|---|---|
ps -o pid,stat,args | PID, state and full command line. |
ps -o pid,vsz,rss,comm | Memory use per process. |
ps -o pid,tty,pgid,sid,comm | Terminal, group and session ids. |
ps -o pid,args | grep '[n]ame' | Find a process without matching grep itself. |
ps | wc -l | Count processes (plus one header line). |
ps -o comm | sort | uniq -c | sort -rn | Which programs run most often. |
Quiz
What does `ps aux` do in the lab VM?
- Shows every process with CPU and memory columns
- Prints the default view: BusyBox ps ignores those letters
- Fails with an error
A process shows STAT `T`. What happened to it?
- It terminated
- It is stopped (Ctrl-Z or SIGSTOP) and can be resumed
- It is waiting on a timer
Why does `ps | grep sleep` show a `grep sleep` line?
- Because grep is a kind of sleep
- Because grep was running, with 'sleep' in its arguments, when ps took the snapshot
- Because of a BusyBox bug
Can you kill a zombie (`Z`) process?
- Yes, with kill -9
- No: it is already dead; its parent must collect it, or the parent must exit
- Only root can
Which column shows the full command line rather than the 15-character name?
- `comm`
- `args`
- `stat`
Practice
A `sleep 1500` is running. Save a listing with the columns PID, STAT and the full command line to `/root/lab/l52/stat.txt`.
Find the running `sleep 1500` with ps and grep and save only its line (not the grep line) to `/root/lab/l52/sleep.txt`.
Count the lines `ps` prints and save just that number to `/root/lab/l52/count.txt`.
Open this lesson in the app to do the tasks in a real Linux machine and have them checked.