Finding Processes: ps aux, pgrep and ps -o

Every process on the machine

Plain ps only shows your terminal. To see everything, from every user, use ps aux (or ps -ef, which shows the same processes in the -f layout). This machine runs a web server and a backup service, like a real server:

ps aux

In the terminal

student@vulntech:~$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.2  0.3   1636   864 ?        Ss   14:31   0:03 /sbin/init
root         2  0.0  0.0      0     0 ?        S    14:31   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    14:31   0:00 [pool_workqueue
root         4  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-kvfr
root         5  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-rcu_
root         6  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-sync
root         7  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-slub
root         8  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-netn
root         9  0.0  0.0      0     0 ?        I    14:31   0:00 [kworker/0:0-ev
root        10  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/0:0H-e
root        11  0.0  0.0      0     0 ?        I    14:31   0:00 [kworker/0:1-mm
root        13  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-mm_p
root        14  0.2  0.0      0     0 ?        I    14:31   0:02 [kworker/u4:1-e
root        15  0.0  0.0      0     0 ?        I    14:31   0:00 [rcu_tasks_kthr
root        16  0.0  0.0      0     0 ?        I    14:31   0:00 [rcu_tasks_trac
root        17  0.0  0.0      0     0 ?        S    14:31   0:00 [ksoftirqd/0]
root        18  0.1  0.0      0     0 ?        I    14:31   0:02 [rcu_preempt]
root        19  0.0  0.0      0     0 ?        S    14:31   0:00 [rcu_exp_par_gp
root        20  0.0  0.0      0     0 ?        S    14:31   0:00 [rcu_exp_gp_kth
root        21  0.0  0.0      0     0 ?        S    14:31   0:00 [migration/0]
root        22  0.0  0.0      0     0 ?        S    14:31   0:00 [cpuhp/0]
root        23  0.0  0.0      0     0 ?        S    14:31   0:00 [kdevtmpfs]
root        24  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-inet
root        25  0.0  0.0      0     0 ?        S    14:31   0:00 [kauditd]
root        26  0.0  0.0      0     0 ?        S    14:31   0:00 [oom_reaper]
root        27  0.0  0.0      0     0 ?        I    14:31   0:00 [kworker/u4:2-e
root        28  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-writ
root        29  0.0  0.0      0     0 ?        S    14:31   0:00 [kcompactd0]
root        30  0.0  0.0      0     0 ?        SN   14:31   0:00 [ksmd]
root        31  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-kint
root        32  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-kblo
root        33  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-blkc
root        34  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-ata_
root        35  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-md]
root        36  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-md_b
root        37  0.0  0.0      0     0 ?        S    14:31   0:00 [watchdogd]
root        39  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-quot
root        40  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/0:1H-k
root        50  0.0  0.0      0     0 ?        S    14:31   0:00 [kswapd0]
root        56  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-kthr
root       100  0.0  0.0      0     0 ?        S    14:31   0:00 [scsi_eh_0]
root       110  0.0  0.0      0     0 ?        I    14:31   0:00 [kworker/u4:6-e
root       115  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-scsi
root       117  0.0  0.0      0     0 ?        S    14:31   0:00 [scsi_eh_1]
root       120  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-scsi
root       141  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-mld]
root       148  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-ipv6
root       149  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/R-kstr
root       307  0.0  0.0      0     0 ?        I    14:31   0:00 [kworker/u4:9-e
root       406  0.0  0.0      0     0 ?        I<   14:31   0:00 [kworker/u5:0]
root      1251  0.0  0.7   2264  1612 ttyS1    Ss+  14:32   0:01 /bin/bash /usr/
root      1292  0.0  0.4   1460  1052 ttyS0    Ss   14:32   0:00 /bin/login -f -
student   1294  0.2  1.4   3408  3152 ttyS0    S    14:32   0:03 -bash
www       1604  2.1  0.7   2256  1600 ?        Ss   14:53   0:00 /bin/bash /usr/
www       1611  3.8  0.7   2256  1604 ?        Ss   14:53   0:00 /bin/bash /usr/
backup    1618  5.6  0.7   2256  1636 ?        Ss   14:53   0:00 /bin/bash /usr/
student   1633  518  0.6   2340  1548 ttyS0    R+   14:53   0:01 ps aux
ColumnMeaning
USERWho the process runs as
PIDIts process ID
%CPU / %MEMHow much of the CPU and memory it uses
RSSMemory in use, in kilobytes
TTYIts terminal; ? means none (a background service)
STATIts state: R running, S sleeping (waiting), T stopped, Z zombie (finished, not yet cleaned up)
START / TIMEWhen it started, and the CPU time it has used
COMMANDThe command line that started it

Names in [square brackets] aren't programs from the disk: they're kernel threads, parts of Linux itself doing housekeeping. Most processes sleep (S) nearly all the time, waiting for something to do.

Looking for one process

The list is long, so you'll often pipe it through grep:

ps aux | grep webserver

In the terminal

student@vulntech:~$ ps aux | grep webserver
www       1604  1.8  0.7   2256  1604 ?        Ss   14:56   0:00 /bin/bash /usr/local/bin/webserver
www       1611  6.1  0.7   2256  1600 ?        Ss   14:56   0:00 /bin/bash /usr/local/bin/webserver
student   1634 30.2  0.3   1908   852 ttyS0    S+   14:57   0:00 grep --color=auto webserver

Notice the extra line at the end: grep webserver itself was running and matched its own search. pgrep is made for the job and doesn't find itself. -a shows the whole command line, -u only looks at one user's processes, and -c just counts:

pgrep webserver
pgrep -a webserver
pgrep -u backup -a
pgrep -c webserver

In the terminal

student@vulntech:~$ pgrep webserver
1604
1610
student@vulntech:~$ pgrep -a webserver
1604 /bin/bash /usr/local/bin/webserver
1610 /bin/bash /usr/local/bin/webserver
student@vulntech:~$ pgrep -u backup -a
1618 /bin/bash /usr/local/bin/backup-agent --target /var/backups --password=Hunter2
student@vulntech:~$ pgrep -c webserver
2

Common mistake: Look at the backup service's command line: anyone on the machine can read it with ps, including the password it was given. Never put secrets on a command line; real programs read them from a protected file or an environment variable.

Choosing the columns: ps -o

-o picks the columns you want, and --sort orders the list (- for biggest first). Here are the five processes using the most memory:

ps -eo pid,user,rss,comm --sort=-rss | head -n 6

In the terminal

student@vulntech:~$ ps -eo pid,user,rss,comm --sort=-rss | head -n 6
  PID USER       RSS COMMAND
 1294 student   3152 bash
 1634 student   2108 head
 1618 backup    1644 backup-agent
 1604 www       1616 webserver
 1251 root      1612 vt-agent

-e means every process, and comm is the short program name. -C name selects processes by program name, and = after a column hides its heading, which is handy in scripts:

ps -o user=,pid=,args= -C backup-agent

In the terminal

student@vulntech:~$ ps -o user=,pid=,args= -C backup-agent
backup    1617 /bin/bash /usr/local/bin/backup-agent --target /var/backups --pas

Remember: ps aux lists every process. pgrep -a name finds one by name. ps -o chooses the columns.

HOME LEARN COMMUNITY DASHBOARD
Practice terminal Starting…