ps

When it comes to process monitoring the command par excellence we can’t do without is ps:

marc:~> ps
  PID TTY           TIME CMD
18934 pts/3     00:00:00 ps
30114 pts/3     00:00:00 bash

Running ps without any arguments give us a short list of processes owned by us (the current user) with their process ID (PID), terminal (TTY), CPU time consumed (TIME) and command being executed. We can use the “-f” flag to add the UID, parent process ID (PPID), CPU utilisation (C) and start time (STIME):

marc:~> ps ­-f
UID        PID  PPID C STIME TTY            TIME CMD
marc     18971 30114 0 09:34 pts/3      00:00:00 ps ­-f
marc     30114 2681  0 Oct16 pts/3      00:00:00 bash

With the “-r” flag only running or runable processes will be shown (STAT = R):

marc:~> ps ­-rf
  PID TTY      STAT     TIME COMMAND
19022 pts/3    R+      0:00  ps ­-rf

And with the “-e” flag all processes running regardless of their owner will be shown:

marc:~> ps -­ef
UID      PID  PPID C STIME TTY           TIME CMD
root       1     0 0 Oct15 ?         00:00:24 /usr/lib/systemd/systemd ­­–switched-­root
root       2     0 0 Oct15 ?         00:00:00 [kthreadd]
root       3     2 0 Oct15 ?         00:00:01 [ksoftirqd/0]
root       7     2 0 Oct15 ?         00:00:27 [rcu_sched]
root       8     2 0 Oct15 ?         00:00:00 [rcu_bh]
root       9     2 0 Oct15 ?         00:00:07 [rcuos/0]
root      10     2 0 Oct15 ?         00:00:00 [rcuob/0]
root      11     2 0 Oct15 ?         00:00:00 [migration/0]
[…]

If we want to list just one particular process we can do so by passing its PID:

marc:~> ps 6885
  PID  TTY      STAT     TIME COMMAND
 6885  ?        Ss       0:01 /usr/lib/systemd/systemd-­journald

If we want to list more than one process then we would need to use the “-p” flag:

marc:~> ps ­-p 28500,28529
  PID TTY         TIME CMD
28500 ?       00:00:00 xfsaild/dm­7
28529 ?       00:00:00 xfs­buf/dm­8

We can list processes running a certain binary or script with the “-C” flag:

marc:~> ps -­C sudo,bash
  PID TTY             TIME CMD
 2687 pts/0       00:00:00 bash
 3963 pts/2       00:00:00 sudo
 3971 pts/2       00:00:00 bash
10286 pts/4       00:00:00 bash
15342 pts/2       00:00:00 bash
25045 pts/0       00:00:00 sudo

We can list processes by their effective (-u) or real (-U) UID, or their effective (-g) or real (-G) GID:

marc:~> ps -­u oracle
marc:~> ps ­-U oracle
marc:~> ps ­-g dba
marc:~> ps -­G dba

We can list process that have a certain parent ID:

marc:~> ps –­­ppid 2177
  PID TTY           TIME CMD
 2266 ?         00:00:10 gnome-­settings­
 2338 ?         00:17:29 gnome­-shell
 2512 ?         00:01:24 tracker­-miner­f
 2515 ?         00:00:40 tracker­-extract
 2538 ?         00:00:00 evolution-­alarm
 2545 ?         00:00:00 gnome-­software
 2546 ?         00:00:00 seapplet

And we can list by terminal with the “-t” flag:

marc:~> ps -­t pts/2,pts/3
  PID TTY              TIME CMD
 3963 pts/2        00:00:00 sudo
 3968 pts/2        00:00:00 su
 3971 pts/2        00:00:00 bash
15342 pts/2        00:00:00 bash
19987 pts/3        00:00:00 ps
30114 pts/3        00:00:00 bash

When it comes to formatting and output we can use “-F” to get the virtual size in pages (SZ = code+data+stack), the resident size (RSS = non-swapped physical memory in Kbytes) and the processor the process is assigned to (PSR):

marc:~> ps ­-F
UID         PID    PPID C      SZ    RSS PSR STIME TTY             TIME CMD
marc      20019   30114 0   34975   3448   3 10:52 pts/3       00:00:00 ps ­-F
marc      30114    2681 0   28973   3740   7 Oct16 pts/3       00:00:00 bash

To show the SELinux process a context is running on we should use “-Z“:

marc:~> ps ­-Z
LABEL                                                  PID TTY            TIME CMD
unconfined_u:unconfined_r:unconfined_t:s0­s0:c0.c1023 20030 pts/3      00:00:00 ps
unconfined_u:unconfined_r:unconfined_t:s0­s0:c0.c1023 30114 pts/3      00:00:00 bash

To show processes’ percentage CPU and memory utilisation, virtual size, resident size and status we should use “-u” (to show only our processes):

marc:~> ps -­u
USER       PID %CPU %MEM    VSZ  RSS TTY     STAT  START    TIME COMMAND
marc      2687  0.0  0.0 115884 3580 pts/0   Ss    Oct15    0:00 bash
marc     10286  0.0  0.0 115896 3624 pts/4   Ss+   Oct17    0:00 bash
marc     15342  0.0  0.0 115884 3576 pts/2   Ss    Oct16    0:00 bash
marc     20034  0.0  0.0 139904 3460 pts/3   R+    10:55    0:00 ps ­-u
marc     30114  0.0  0.0 115892 3740 pts/3   Ss    Oct16    0:00 bash

We can see the threads by using the “-L” flag:

marc:~> ps ­-p 1316 ­-L -­f
UID       PID PPID    LWP C NLWP STIME TTY        TIME CMD
root     1316    1   1316 0   11 Oct15 ?      00:00:41 /usr/sbin/libvirtd
root     1316    1   1329 0   11 Oct15 ?      00:00:08 /usr/sbin/libvirtd
root     1316    1   1330 0   11 Oct15 ?      00:00:08 /usr/sbin/libvirtd
root     1316    1   1331 0   11 Oct15 ?      00:00:08 /usr/sbin/libvirtd

The command field is truncated by default if it exceeds a certain length. If we do not want that, we can use either -w or -ww:

marc:~> ps -­fww ­-p 11311
UID         PID PPID C STIME TTY         TIME CMD
qemu      11311    1 1 Oct16  ?      00:49:06 /usr/bin/qemu­system­x86_64 ­machine accel=kvm
­name rhel7.0 ­S ­machine pc­i440fx­2.1,accel=kvm,usb=off ­cpu Westmere ­m 4096 ­realtime
mlock=off ­smp 4,sockets=4,cores=1,threads=1 ­uuid 431708b0­09ce­4ff3­84bf­65220af3f043 ­no­user­
config ­nodefaults ­chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/rhel7.0.monitor,server,nowait ­mon  chardev=charmonitor,id=monitor,mode=control ­rtc base=utc,driftfix=slew ­global kvm­
[…]

We can specify what columns we want and the headers they should have:

marc:~> ps ­-o pid,tty=TTY,stat ­-o nlwp=#THREADS
  PID TTY    STAT #THREADS
20571 pts/3  R+          1
30114 pts/3  Ss          1

And we can determine the sorting order with the –sort option and the column names with “” (descending order) and “+” (ascending order):

marc:~> ps ­-e -­o pid,tty=TTY,stat ­-o nlwp=#THREADS ­-o rss -­o command ­­–sort=­-nlwp,+rss
  PID TTY STAT #THREADS   RSS  COMMAND
13820 ?   Sl         43 174592 /usr/lib64/spotify­client/spotify
 5001 ?   SLl        43 324724 /opt/google/chrome/chrome
 5323 ?   Sl         16 315116 /opt/google/chrome/chrome ­­type=renderer ­­lang=en­US …
 2515 ?   SNl        14 58936  /usr/libexec/tracker­extract
 5133 ?   Sl         13 107696 /opt/google/chrome/chrome ­­type=renderer ­­lang=en­US …
 1316 ?   Ssl        11 42804  /usr/sbin/libvirtd
13857 ?   Sl         10 172052 /usr/lib64/spotify­client/spotify ­­type=renderer ­­no­ …
 2569 ?   Sl          9 205692 ./insync start
 2527 ?   Sl          8 136832 /usr/libexec/tracker­store

The list of columns and aliases to show and sort by is quite long, so check man ps to get it. To close the ps section let’s see the CPU states a process can be in:

D   uninterruptible sleep (usually IO)
R   running or runnable (on run queue)
S   interruptible sleep (waiting for an event to complete)
T   stopped by job control signal
t    stopped by debugger during the tracing
Z   defunct (“zombie”) process, terminated but not reaped by its parent

When the stat keyword is used, additional characters may be displayed:

<   high­priority (not nice to other users)
N   low­priority (nice to other users)
L   has pages locked into memory (for real­time and custom IO)
s   is a session leader
l    is multi­threaded (using CLONE_THREAD, like NPTL pthreads do)
+   is in the foreground process group

 

top >>