30 April 2021
The ps
utility displays information about processes. The information shown is similar to the output in the “fields display” of top. The main difference is that ps
takes a single snapshot of processes, while top refreshes the output every few seconds. If you are investigating a high system load then top
is likely to be more useful, but ps
still has its uses.
Most versions of ps
support both Unix and BSD options. The difference between the two is that BSD options don’t use a hyphen. If, for instance, you run the well-known command ps aux
to display information about all processes for all users (a
) together with the process’ user (u
) and processes that aren’t attached to a terminal (x
) then you are using a BSD-style command. This is different from ps -aux
, which prints all processes (-a
) owned by the user (-u
) named x (x
).
The command ps -aux
still works if there is no user named x on your system – the utility is smart enough to realise that you probably want to list all processes. Nevertheless, it is best to stick with either the Unix or BSD-style options. In this article I will use Unix-style options.
The Unix-style alternative for ps aux
is ps -e
:
# ps -e PID TTY TIME CMD 1 ? 00:01:00 systemd 2 ? 00:00:00 kthreadd ... 35 ? 00:00:00 oom_reaper 1647 ? 00:00:05 php-fpm 1712 ? 00:00:00 php-fpm 1713 ? 00:00:00 php-fpm ... 1726 ? 00:00:00 httpd 1728 ? 00:00:27 httpd 1729 ? 00:00:21 httpd 1730 ? 00:00:21 httpd ...
I have shortened the output for readability. The main thing to focus on are the four columns that are displayed:
You can make the output more verbose by adding the -f
option. This adds four more columns:
# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 Nov20 ? 00:02:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 21 root 2 0 0 Nov20 ? 00:00:00 [kthreadd] ... apache 1911 1064 0 19:29 ? 00:00:07 /usr/sbin/httpd -DFOREGROUND apache 1912 1064 0 19:29 ? 00:00:06 /usr/sbin/httpd -DFOREGROUND apache 1994 1064 0 19:30 ? 00:00:05 /usr/sbin/httpd -DFOREGROUND apache 1995 1064 0 19:30 ? 00:00:06 /usr/sbin/httpd -DFOREGROUND ...
ps
man page: “It will not add up to 100% unless you are lucky.” Also note that this information is unlikely to tell you how much strain your system is currently under – if a process has been running for a long time then any temporary spikes aren’t visible.The -o
option lets you specify what columns are displayed. Multiple columns can be separated with commas. For instance, the below command shows the PID, the command and the time that has elapsed since a process was started:
# ps -eo pid,cmd,etime PID CMD ELAPSED 1 init 589-14:35:45 2 [kthreadd/103022] 589-14:35:45 3 [khelper/103022] 589-14:35:45 ... 2528 /usr/sbin/sshd 15-18:07:42 ... 11469 crond 254-08:04:28
The -o
option has lots of possible values – search the man page for standard format specifiers.
So far our output has been sorted by the process ID. You can specify another sort key using the --sort
option. By default, ps
sorts the output in increasing numerical or lexicographic order, which is probably the exact opposite of what you want. It means that if you sort the output by, say, memory usage (pmem
) the process with the least amount of memory usage is listed first. You can reverse the sort order by adding a minus sign before the name of the column:
# ps -eo pid,%cpu,pmem,user,comm --sort=-pmem | head PID %CPU %MEM USER COMMAND 16011 44.1 9.4 mysql mysqld 28327 10.2 2.2 example php-fpm 28328 9.0 2.2 example php-fpm 28370 7.1 1.9 example php-fpm 6687 0.5 1.9 nobody httpd 4929 0.5 1.9 nobody httpd 5219 0.5 1.9 nobody httpd 7087 0.5 1.9 nobody httpd 7315 0.5 1.9 nobody httpd
In the above example processes are sorted by memory usage. You can of course also sort the output by CPU usage:
# ps -eo pid,%cpu,pmem,user,comm --sort=-%cpu | head PID %CPU %MEM USER COMMAND 16011 43.8 9.4 mysql mysqld 28387 7.8 2.3 example php-fpm 28327 7.2 2.2 example php-fpm 28318 6.7 1.9 example php-fpm 28329 6.6 1.8 example php-fpm 28388 6.5 2.1 example php-fpm 28372 6.4 2.0 example php-fpm 28385 6.4 1.9 example php-fpm 28319 6.1 2.2 example php-fpm
The are a couple of other ps
options you should know about. For instance, you can list all the processes that belong to a particular user:
# ps -u example PID TTY TIME CMD 28318 ? 00:01:31 php-fpm 28319 ? 00:00:58 php-fpm 28326 ? 00:00:51 php-fpm 28327 ? 00:01:04 php-fpm 28328 ? 00:00:51 php-fpm ...
If you get a very long list then you may want to get a count of the processes. The below command tells ps
to not print the headers (--no-headers
) and it then pipes the output to an awk command that prints the last column. The last three commands produce a count and sort the output:
# ps --no-headers -u example \ | awk '{print $NF}' \ | sort | uniq -c | sort -hr 21 php-fpm 1 quota-status
Unfortunately, you can’t use the -e
and -u
options together. However, if you want to see the output of, say, ps -ef
for the user example then you can of course pipe the output to grep
:
# ps -ef | grep ^example example 28318 28301 7 12:00 ? 00:01:34 php-fpm: pool example_example.com example 28319 28301 5 12:00 ? 00:01:02 php-fpm: pool example_example.com example 28326 28301 4 12:00 ? 00:00:56 php-fpm: pool example_example.com example 28327 28301 5 12:00 ? 00:01:06 php-fpm: pool example_example.com example 28328 28301 4 12:00 ? 00:00:53 php-fpm: pool example_example.com ...
Note that the caret character (^
) is used to only match strings that begin with the string “example”. Also note that you lose the headers when you use grep
.