Sorting the output of `ps`

processpssort

I am trying to understand why ps does not behave the way I expect it to. From the man pages, the following command should display ppid and lstart, with items sorted by lstart order. However when I run the same command in three different terminals:

First term:

gauthier@sobel:~/ $ ps -o ppid -o lstart --sort=lstart
 PPID                  STARTED
21142 Tue Dec 16 13:45:18 2014
 3383 Mon Dec 15 15:40:35 2014

Second term:

gauthier@sobel:~/bin $ ps -o ppid -o lstart --sort=lstart
 PPID                  STARTED
19595 Tue Dec 16 13:45:03 2014
 3383 Mon Dec 15 14:49:14 2014

Third term:

gauthier@sobel:~ $ ps -o ppid -o lstart --sort=lstart
 PPID                  STARTED
 3383 Tue Dec 16 13:39:05 2014
16357 Tue Dec 16 13:45:12 2014

There are several things I don't understand here.

  • items in terms 1 and 2 are sorted most recent first. Items in term 3 are sorted oldest first. Even considering alphabetical order the orders differ.

  • PPID 3383 is the same for all three terms, but at different start times. It seems that several distinct PPID might be the same although they are different processes?


System info:

$ ps -V
procps-ng version 3.3.9
$ uname -a
Linux sobel 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Best Answer

ps --sort=lstart doesn't actually sort by lstart, According to this serverfault comment:

lstart gives a full timestamp, but cannot be used as a sort key. start_time gives the usual 'time within the last 24 hours, date otherwise' column, and can be used as a sort key.

This is implicitly documented in ps's man pages, where lstart is not listed under the OBSOLETE SORT KEYS section, but start_time is.

The source code also backs this up, see this definition starting on line 1506:

/* Many of these are placeholders for unsupported options. */
static const format_struct format_array[] = {
/* code       header     print()      sort()    width need vendor flags  */
[...]
{"lstart",    "STARTED", pr_lstart,   sr_nop,    24,   0,    XXX, ET|RIGHT},
[...]
{"start_time", "START",  pr_stime,    sr_start_time, 5, 0,   LNx, ET|RIGHT},
[...]
};

Edit: expanded on the explanation on the right answer, and removed the misleading part of the original one.

Related Question