1

Utilities such as ps and top are good for looking at many processes side-by-side. However, they are inconvenient for examining many fields of a single process and are not amenable to using grep. For example:

$ ps -o pid,ppid,tname,bsdstart,start_time,start,bsdtime,etime,etimes,c=LIFE%,%cpu,cputime,rss,%mem,stat,class,nice=NICE,thcount,args -p $(pgrep syncthing)
  PID  PPID TTY       START START  STARTED   TIME     ELAPSED ELAPSED LIFE% %CPU     TIME   RSS %MEM STAT CLS NICE THCNT COMMAND                                               
20149  1836 ?         19:24 19:24 19:24:58   0:24    01:54:12    6852     0  0.3 00:00:24 38428  0.2 Ssl  IDL    -    13 /usr/bin/syncthing -no-browser -no-restart -logflags=0

There is /proc/$PID/status:

$ cat /proc/$(pgrep syncthing)/status | head
Name:   syncthing
Umask:  0022
State:  S (sleeping)
Tgid:   20149
Ngid:   0
Pid:    20149
PPid:   1836
TracerPid:      0
Uid:    1000    1000    1000    1000
Gid:    1000    1000    1000    1000

but this lacks useful fields such as:

  • CPU usage percentage
  • CPU time
  • Resident memory size / resident set size
  • Memory percentage
  • Out of Memory Score
  • Elapsed time
  • Nice priority
  • I/O priority

The output I desire might look something like this:

Name: syncthing
Process ID: 20149
Parent process ID: 1836
Full command: /usr/bin/syncthing
User: exampleuser
UID: 1000
State: Sleeping (S)
CPU priority: 19 (low)
I/O scheduling class: 2 (best-effort)
I/O priority level: 7 (low)
Start date (ISO): 2020-06-15T21:21:53-04:00 
Start date (UTC): Tue Jun 16 01:21:53 UTC 2020
Process age: 01:54:12
Cumulative CPU time: 00:00:24
Cumulative user CPU time: 00:00:24
Cumulative system CPU time: 00:00:24
Out of memory score: 2
Out of memory adjustment factor: 0
Number of threads: 13
Number of child processes: 0

with more fields from e.g. /proc/$PID/stat and /proc/$PID/statm.

Does such a utility exist?

Note: this question differs from Detailed Per-Process Profiling because I am not looking for performance profiling or monitoring over time, but rather a snapshot of process information for the specific fields mentioned above in a particular format.

Nathaniel M. Beaver
  • 1,246
  • 13
  • 28

2 Answers2

2

Yes, such a utility exists. I wrote one. When version 1.41 of the nosh toolkit comes out, it will be available.

Fields are emitted in vis(3) encoded form, precisely so that they are machine-parseable by tools that break fields on whitespace. One can, for example, feed the output into awk and do awk's usual field matching, without (as is well-known to be the case with passing the vanilla ps programs' outputs through grep) accidentally matching something from another field. Then one passes it through unvis to get the human-readable form.

Here is how I recently looked for my own processes, for example:

system-control ps -A -o "pid,args,stime,tree,tty,uid" | 
awk -F$'\t' '{ if ($6==1001) printf "%8u %4u %s %s [%s] %s\\n",$1,$6,$3,$4,$5,$2 }' |
unvis |
less -S

I'd modified a previous command in my history, adding in the uid field and the matching on field number 6. This sort of thing breaks with the vanilla ps commands, because args does not get recognized as one field. The vis(3) encoding here ensures that it does.

It fishes a whole bunch of stuff out of stat on Linux. (The tool works on both Linux-based operating systems and FreeBSD.) Columns are selectable via -o and -O if one uses the compatibility shim, as shown here.

Its output is actually a proper, machine-parseable, flat file table, single-TAB-separated. Indeed, one can turn this into your chosen form with Miller and suchlike:

% system-control ps -A -o "pid,args,stime,uid" |
awk '$4==1001 || NR==1' |
mlr --oxtab --ipprint --ifs '\t' --ops ': ' cat |
unvis |
head -n 10
PID: 4140
COMMAND: -zsh
STIME: 2020-06-16 08:39:05
UID: 1001

PID: 4554
COMMAND: sh /tmp/PCDM-session.sD4542
STIME: 2020-06-16 08:39:19
UID: 1001

%

Notice the spaces in two fields, which have remained encoded through processing until unvis.

Tools to get reliably-machine-processable process listings do indeed exist. They are just not the (not really) standard ps command, or top.

Further reading

  • vis. NetBSD Library Functions Manual. 2017-04-22.
  • unvis. FreeBSD General Commands Manual. 2010-11-27.
  • Jonathan de Boyne Pollard (2020). ps. nosh Guide. Softwares.
  • Jonathan de Boyne Pollard (2020). list-process-table. nosh Guide. Softwares.
JdeBP
  • 66,967
  • 12
  • 159
  • 343
1

The procinfo.py script does this, available in the source code of the python psutil library. It is not, however, generally packaged with psutil itself.

Here is an example of its output:

$ procinfo.py $(pgrep syncthing)
pid         19383
name        syncthing
parent      1836 (syncthing)
exe         /usr/bin/syncthing
cwd         /home/nathaniel
cmdline     /usr/bin/syncthing -no-browser -no-restart -logflags=0
started     2020-06-18 18:04
cpu-tspent  0:28.66
cpu-times   user=19.73, system=8.93, children_user=0.0, children_system=0.0
cpu-affinity [0, 1, 2, 3]
cpu-num     1
memory      rss=42.3M, vms=927.6M, shared=14.6M, text=6.2M, lib=0B, data=129.5M, dirty=0B
memory %    0.27
user        nathaniel
uids        real=1000, effective=1000, saved=1000
uids        real=1000, effective=1000, saved=1000
terminal    
status      sleeping
nice        0
ionice      class=3, value=0
num-threads 13
num-fds     21
I/O         read_count=8.9K, write_count=1.6K, read_bytes=2.9M, write_bytes=896.0K, read_chars=2.1M, write_chars=126.2K
ctx-switches voluntary=32, involuntary=1
open-files  PATH
            /home/nathaniel/.config/syncthing/index-v0.14.0.db/LOCK
            /home/nathaniel/.config/syncthing/index-v0.14.0.db/LOG
            /home/nathaniel/.config/syncthing/index-v0.14.0.db/006717.log
            /home/nathaniel/.config/syncthing/index-v0.14.0.db/MANIFEST-006718
            [...]
connections PROTO LOCAL ADDR                REMOTE ADDR               STATUS
            TCP   192.168.1.153:57054       216.59.50.190:22067       ESTABLISHED
            UDP   :::35882                  *:*                       NONE
            TCP   192.168.1.153:45342       198.211.120.59:443        ESTABLISHED
            TCP   ::ffff:192.168.1.153:22000 ::ffff:192.168.1.175:41196 ESTABLISHED
            UDP   0.0.0.0:21027             *:*                       NONE
            UDP   :::21027                  *:*                       NONE
            UDP   0.0.0.0:33035             *:*                       NONE
            TCP   :::22000                  *:*                       LISTEN
            TCP   127.0.0.1:8384            *:*                       LISTEN
            UDP   :::22020                  *:*                       NONE
threads     TID           USER       SYSTEM
            19383         0.01          0.0
            19384         0.89         2.63
            19385          0.0          0.0
            19386          2.2          0.5
            [...]
            total=13
res-limits  RLIMIT                  SOFT            HARD
            virtualmem          infinity        infinity
            coredumpsize               0        infinity
            cputime             infinity        infinity
            datasize            infinity        infinity
            filesize            infinity        infinity
            locks               infinity        infinity
            memlock             16777216        16777216
            msgqueue              819200          819200
            nice                       0               0
            openfiles               4096            4096
            maxprocesses           63289           63289
            rss                 infinity        infinity
            realtimeprio               0               0
            rtimesched          infinity        infinity
            sigspending            63289           63289
            stack                8388608        infinity
environ     NAME                      VALUE
            ACK_PAGER                 less --RAW-CONTROL-CHARS --no-init --quit-if-one-screen
            APPORT_IGNORE_OBSOLETE_PACKAGES 1
            BROWSER                   /usr/bin/firefox
            DBUS_SESSION_BUS_ADDRESS  unix:path=/run/user/1000/bus
            [...]
mem-maps    RSS      PATH
            28.3M    [anon]
            12.9M    /usr/bin/syncthing
            1.6M     /lib/x86_64-linux-gnu/libc-2.27.so
            164.0K   /lib/x86_64-linux-gnu/ld-2.27.so
            [...]
Nathaniel M. Beaver
  • 1,246
  • 13
  • 28