The ps command gives information about processes on a Linux or Unix system. Our programs run as processes in the system. Also, for each installed package, there might be one or more processes. So, to know what is happening in the system, the first instinctive action is to find out about processes running in the system by using the ps command.
ps -ef
To find out information about all the processes in the system, the command is,
ps -ef
The above command gives the output like,
UID PID PPID C STIME TTY TIME CMD root 1 0 0 Feb20 ? 00:00:01 /sbin/init root 2 0 0 Feb20 ? 00:00:00 [kthreadd] root 3 2 0 Feb20 ? 00:02:22 [ksoftirqd/0] root 6 2 0 Feb20 ? 00:00:00 [migration/0] root 7 2 0 Feb20 ? 00:00:00 [migration/1] root 9 2 0 Feb20 ? 00:13:44 [ksoftirqd/1] root 11 2 0 Feb20 ? 00:00:00 [cpuset] root 12 2 0 Feb20 ? 00:00:00 [khelper] .... root 735 2 0 Feb20 ? 00:00:00 [jbd2/sda6-8] root 769 2 0 Feb20 ? 00:00:00 [ext4-dio-unwrit] root 773 2 0 Feb20 ? 00:00:00 [hd-audio0] root 842 1 0 Feb20 ? 00:00:00 /usr/sbin/sshd -D 103 860 1 0 Feb20 ? 00:02:28 dbus-daemon --system --fork --activation=upstart root 868 1 0 Feb20 ? 00:00:00 /usr/sbin/modem-manager avahi 872 1 0 Feb20 ? 00:00:02 avahi-daemon: running [flute.local] root 874 1 0 Feb20 ? 00:00:52 NetworkManager root 1008 990 2 Feb20 tty7 02:44:38 /usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch -background none root 1053 1 0 Feb20 ? 00:00:00 /usr/sbin/bluetoothd root 1058 2 0 Feb20 ? 00:00:00 [krfcommd] root 1142 2 0 Feb20 ? 00:00:11 [flush-8:0] ....
The -e option selects all processes in the system. Without this, ps gives the processes belonging to the same effective user id as the user giving the command and also started from the current terminal. The -f option gives the full
listing. Without it, ps -e
command would have just listed all the processes but with lesser number of attributes.
In the ps output, the first column gives the process owner's user-id. The second column gives the process-id, the unique id of the process in the system. The third column gives the parent process id. The next column, with heading C, represents CPU utilization. It is the CPU time used by the process divided by the clock time the process has been running, expressed as the integer value of the percentage. A high value for C indicates a CPU intensive process. The next two columns give the process start time and the terminal from which the process has been started respectively. The next column gives the cumulative CPU time used by the process in [DD-]hh:mm:ss format. Finally, we have the command, using which, the process was created.
Quite often, the ps command is used in conjunction with the grep command, to filter out processes matching a certain pattern. For example,
$ ps -ef | grep "nginx" root 2120 1 0 Dec11 ? 00:00:00 nginx: master process /eph/sbin/nginx -g daemon on; master_process on; www-data 2121 2120 0 Dec11 ? 00:18:05 nginx: worker process www-data 2122 2120 0 Dec11 ? 00:00:36 nginx: worker process ubuntu 160445 159987 0 20:32 pts/0 00:00:00 grep --color=auto nginx
ps -eF
The -f option gives the full format listing. However there is a -F option, which is the extra full format. So the command,
ps -eF
gives the output,
UID PID PPID C SZ RSS PSR STIME TTY TIME CMD root 1 0 0 830 1152 0 Feb20 ? 00:00:01 /sbin/init root 2 0 0 0 0 0 Feb20 ? 00:00:00 [kthreadd] root 3 2 0 0 0 0 Feb20 ? 00:02:23 [ksoftirqd/0] root 6 2 0 0 0 0 Feb20 ? 00:00:00 [migration/0] root 7 2 0 0 0 1 Feb20 ? 00:00:00 [migration/1] root 9 2 0 0 0 1 Feb20 ? 00:13:48 [ksoftirqd/1] root 11 2 0 0 0 0 Feb20 ? 00:00:00 [cpuset] root 12 2 0 0 0 0 Feb20 ? 00:00:00 [khelper] root 13 2 0 0 0 1 Feb20 ? 00:00:00 [netns] root 14 2 0 0 0 1 Feb20 ? 00:00:00 [kworker/u:1] root 15 2 0 0 0 1 Feb20 ? 00:00:00 [sync_supers] root 988 1 0 496 520 1 Feb20 ? 00:00:00 acpid -c /etc/acpi/events -s /var/run/acpid.socket .... root 990 1 0 10287 1360 1 Feb20 ? 00:00:00 lightdm root 1001 1 0 855 496 1 Feb20 ? 00:01:34 /usr/sbin/irqbalance root 1006 1 0 607 676 0 Feb20 ? 00:00:01 cron daemon 1007 1 0 570 96 1 Feb20 ? 00:00:00 atd root 1008 990 2 28109 106772 0 Feb20 tty7 02:46:44 /usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch -background none root 1053 1 0 1124 684 0 Feb20 ? 00:00:00 /usr/sbin/bluetoothd root 1058 2 0 0 0 0 Feb20 ? 00:00:00 [krfcommd] root 1142 2 0 0 0 1 Feb20 ? 00:00:12 [flush-8:0] root 1188 1 0 492 464 0 Feb20 tty1 00:00:00 /sbin/getty -8 38400 tty1 root 1194 1 0 3942 1568 0 Feb20 ? 00:00:10 /usr/lib/accountsservice/accounts-daemon root 1201 1 0 6957 1292 1 Feb20 ? 00:00:01 /usr/sbin/console-kit-daemon --no-daemon root 1305 1 0 6743 1968 1 Feb20 ? 00:00:01 /usr/lib/upower/upowerd rtkit 1407 1 0 4772 432 0 Feb20 ? 00:00:05 /usr/lib/rtkit/rtkit-daemon ....
Compared with the -f option, the -F option gives three additional columns of output. The SZ column gives the virtual size of the process, code, data and stack segments taken together. RSS is the resident set size, the non-swapped physical memory that the process has used in kilobytes. PSR indicates the processor that the process is currently assigned to.
ps -eLF
The -L option is for getting information about the threads. The command,
ps -eLF
gives the output,
UID PID PPID LWP C NLWP SZ RSS PSR STIME TTY TIME CMD root 1 0 1 0 1 830 1148 0 Feb20 ? 00:00:01 /sbin/init root 2 0 2 0 1 0 0 0 Feb20 ? 00:00:00 [kthreadd] root 3 2 3 0 1 0 0 0 Feb20 ? 00:02:23 [ksoftirqd/0] root 6 2 6 0 1 0 0 0 Feb20 ? 00:00:00 [migration/0] root 7 2 7 0 1 0 0 1 Feb20 ? 00:00:00 [migration/1] root 9 2 9 0 1 0 0 1 Feb20 ? 00:13:50 [ksoftirqd/1] root 11 2 11 0 1 0 0 0 Feb20 ? 00:00:00 [cpuset] root 12 2 12 0 1 0 0 0 Feb20 ? 00:00:00 [khelper] root 13 2 13 0 1 0 0 1 Feb20 ? 00:00:00 [netns] root 14 2 14 0 1 0 0 1 Feb20 ? 00:00:00 [kworker/u:1] .... root 842 1 842 0 1 1606 664 0 Feb20 ? 00:00:00 /usr/sbin/sshd -D syslog 852 1 852 0 4 7260 824 1 Feb20 ? 00:00:50 rsyslogd -c5 syslog 852 1 859 0 4 7260 824 1 Feb20 ? 00:00:10 rsyslogd -c5 syslog 852 1 889 0 4 7260 824 1 Feb20 ? 00:00:00 rsyslogd -c5 syslog 852 1 890 0 4 7260 824 1 Feb20 ? 00:00:00 rsyslogd -c5 103 860 1 860 0 1 1102 1828 1 Feb20 ? 00:02:30 dbus-daemon --system --fork --activation=upstart root 868 1 868 0 1 1716 1196 1 Feb20 ? 00:00:00 /usr/sbin/modem-manager avahi 872 1 872 0 1 829 760 1 Feb20 ? 00:00:02 avahi-daemon: running [flute.local] avahi 873 872 873 0 1 829 124 1 Feb20 ? 00:00:00 avahi-daemon: chroot helper root 874 1 874 0 3 7012 2604 1 Feb20 ? 00:00:52 NetworkManager root 874 1 891 0 3 7012 2604 1 Feb20 ? 00:00:00 NetworkManager root 874 1 1651 0 3 7012 2604 0 Feb20 ? 00:00:00 NetworkManager root 893 1 893 0 2 6120 1644 0 Feb20 ? 00:00:00 /usr/lib/policykit-1/polkitd root 893 1 898 0 2 6120 1644 1 Feb20 ? 00:00:02 /usr/lib/policykit-1/polkitd root 952 1 952 0 1 492 460 1 Feb20 tty4 00:00:00 /sbin/getty -8 38400 tty4 ....
This gives one line of information per thread. So single threaded processes occupy one line each in the output. Multi-threaded processes occupy as many lines in the output as the number of threads in the relevant process. There are two additional columns, LWP and NLWP. LWP gives the thread id of each thread. NLWP is the number of threads in the system for the underlying process. In the ps output above, rsyslogd (pid 852) has 4 threads, NetworkManager (pid 874) has three threads and polkitd (pid 893) has two threads. The -L option gives an idea about the total number of concurrent threads in the system. We can see which process is creating more threads and then analyze whether that many threads for a given process are justified or not.
ps -u
The “-u” option tells what processes are running for the indicated user. For example, to know what processes are running for the user, “www-data”, we can give the command,
$ ps -u www-data PID TTY TIME CMD 2121 ? 00:18:01 nginx 2122 ? 00:00:36 nginx 146894 ? 00:04:35 php-fpm7.4 154569 ? 00:01:16 php-fpm7.4 159839 ? 00:00:00 php-fpm7.4
Of course, we could have used the “-f” option and got the “fuller” output.
$ ps -f -u www-data UID PID PPID C STIME TTY TIME CMD www-data 2121 2120 0 Dec11 ? 00:18:01 nginx: worker process www-data 2122 2120 0 Dec11 ? 00:00:36 nginx: worker process www-data 146894 70305 0 Dec26 ? 00:04:35 php-fpm: pool www www-data 154569 70305 0 05:05 ? 00:01:16 php-fpm: pool www www-data 159839 70305 0 19:12 ? 00:00:01 php-fpm: pool www
ps -t
The “ps -t” command helps in finding processes running on a terminal. This is particularly useful when a terminal gets “stuck” and you wish to “release” the terminal by killing the processes running on it. For example,
$ ps -t pts/0 PID TTY TIME CMD 159987 pts/0 00:00:00 bash 160226 pts/0 00:00:00 ps $ kill -9 159987
ps -p
Suppose you want information for a list of processes, the command is
ps -p pidlist
For example,
$ ps -f -p 1853,1941,3542 UID PID PPID C STIME TTY TIME CMD user1 1853 1742 0 08:42 ? 00:00:08 /usr/bin/ibus-daemon --daemonize --xim user1 1941 1742 0 08:42 ? 00:00:00 /usr/bin/pulseaudio --start --log-target=syslog user1 3542 2445 8 12:41 ? 00:00:28 /opt/google/chrome/chrome --type=renderer --enable-deferred-image-decoding --lang=en-US --force-fieldt
Customizing the ps output format
In the above examples the output format is governed by the options like -f and -F. However, we can customize the output using the -o option. The command,
ps -eo uname,pid,ppid,nlwp,pcpu,pmem,psr,start_time,tty,time,args
gives the output,
USER PID PPID NLWP %CPU %MEM PSR START TT TIME COMMAND root 1 0 1 0.0 0.1 1 Feb20 ? 00:00:01 /sbin/init root 2 0 1 0.0 0.0 0 Feb20 ? 00:00:00 [kthreadd] root 3 2 1 0.0 0.0 0 Feb20 ? 00:02:23 [ksoftirqd/0] root 6 2 1 0.0 0.0 0 Feb20 ? 00:00:00 [migration/0] root 7 2 1 0.0 0.0 1 Feb20 ? 00:00:00 [migration/1] root 9 2 1 0.1 0.0 1 Feb20 ? 00:13:52 [ksoftirqd/1] root 11 2 1 0.0 0.0 0 Feb20 ? 00:00:00 [cpuset] root 12 2 1 0.0 0.0 0 Feb20 ? 00:00:00 [khelper] root 13 2 1 0.0 0.0 1 Feb20 ? 00:00:00 [netns] root 14 2 1 0.0 0.0 1 Feb20 ? 00:00:00 [kworker/u:1] .... root 1008 990 1 2.2 11.4 1 Feb20 tty7 02:48:09 /usr/bin/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch -background none root 1053 1 1 0.0 0.0 0 Feb20 ? 00:00:00 /usr/sbin/bluetoothd root 1058 2 1 0.0 0.0 0 Feb20 ? 00:00:00 [krfcommd] root 1142 2 1 0.0 0.0 0 Feb20 ? 00:00:12 [flush-8:0] root 1188 1 1 0.0 0.0 0 Feb20 tty1 00:00:00 /sbin/getty -8 38400 tty1 root 1194 1 2 0.0 0.1 0 Feb20 ? 00:00:11 /usr/lib/accountsservice/accounts-daemon root 1201 1 65 0.0 0.1 1 Feb20 ? 00:00:01 /usr/sbin/console-kit-daemon --no-daemon root 1305 1 3 0.0 0.2 1 Feb20 ? 00:00:01 /usr/lib/upower/upowerd rtkit 1407 1 3 0.0 0.0 0 Feb20 ? 00:00:05 /usr/lib/rtkit/rtkit-daemon user1 1503 1 5 0.0 0.1 1 Feb20 ? 00:00:02 /usr/bin/gnome-keyring-daemon --daemonize --login user1 1512 990 4 0.0 0.2 1 Feb20 ? 00:00:06 /usr/bin/gnome-session --session=ubuntu user1 1549 1512 1 0.0 0.0 0 Feb20 ? 00:00:02 /usr/bin/ssh-agent /usr/bin/dbus-launch --exit-with-session /usr/bin/gnome-session --session=ubuntu user1 1552 1 1 0.0 0.0 1 Feb20 ? 00:00:00 /usr/bin/dbus-launch --exit-with-session /usr/bin/gnome-session --session=ubuntu user1 1553 1 1 0.2 0.2 0 Feb20 ? 00:15:12 //bin/dbus-daemon --fork --print-pid 8 --print-address 10 --session ....
The pcpu option gives the CPU utilization of the process under the column %CPU. It is the CPU time used by the process divided by the real clock time the process has been running, given as a percentage. Similarly, the pmem option gives the memory utilization of the process, being the ratio of process's resident set size (RSS) to the total physical memory on the machine, given as a percentage. The nlwp option gives the number of threads in a process, as before. We got the details one line per process, as shown above. If information was required for each thread, we could have given the command,
ps -eLo uname,pid,ppid,nlwp,lwp,pcpu,pmem,psr,start_time,tty,time,args
Sorting the ps output
We can sort the ps command output using the –sort spec option. The spec is [+|-]key[,[+|-]key[…]]. The + sign is the default and indicates increasing numerical or lexicographic order. So, if we wish to know the processes consuming high CPU and memory, the following ps command would do the job.
ps -eo uname,pid,ppid,nlwp,pcpu,pmem,psr,start_time,tty,time,args --sort -pcpu,-pmem
Skipping headers
Suppose you wish to use ps in a script and do not want it to print headers in output, you can use the –no-headers option. For example, the following command pipeline prints the user-id, process-id, CPU time and the command name of the top five CPU intensive processes.
ps -ef --no-headers --sort -pcpu | sed '5q' | awk ' { print $1, $2, $7, $8 }'
Reference
- ps manual entry, given by the command, man ps