Skip to content

How Long has a Process Been Alive?

Knowing how long a process has been running can be useful. Unfortunately, the standard date fields in the ps command use a "scrolling date" display. In other words, it displays uptime differently based on a process's age. Here's an example:

  me@mybox:~$ ps aux
  USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
  nobody   22571  0.0  0.0   2128   244 ?        SN   08:22   0:00 /usr/sbin/tinyproxy
  nobody   22572  0.0  0.0   2128   244 ?        SN   08:22   0:00 /usr/sbin/tinyproxy
  root     21075  0.0  0.0      0     0 ?        S<   Apr26   0:00 [kstriped]
  root     21082  0.0  0.0      0     0 ?        S<   Apr26   0:00 [ksnapd]
  root     17275  0.0  1.5 178952 74028 ?        Ss    2008   0:18 /usr/sbin/httpd
  ....

Notice that the first two processes say 08:22 in the START column. Those processes were started today. I only know that because I read the man page. The next two processes say Apr26 which is clear enough, but I've lost the timestamp. And the last process only says 2008. No date, no time.

This is not a very script-friendly way to display the date. If I wanted to use the start time in a script, I would have to codify the things I mentioned above. In other words, I would need to parse the START column and determine all the parts of the date based on my understanding of ps's behavior. Definitely not a good idea since ps could change.

So how do I find the complete and accurate start time? There are a couple ways.

Method #1: Elapsed Time

I stole this example from the ps man page, with adjustments. The man page says:

  To see every process with a user-defined format:
    ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm

The important thing is the -o command line option which allows me to customize the columns I want to see in the output. Further down the ps man page, I found the STANDARD FORMAT SPECIFIERS section, which revealed these tidbits:

  etime     elapsed time since the process was started, in the form [[dd-]hh:]mm:ss.
  pid       process ID number of the process.
  args      command with all its arguments as a string

So now I can run a simple command:

  me@mybox:~$ ps -eo pid,etime,args
  22571     01:06:40 /usr/sbin/tinyproxy
  22572     01:06:40 /usr/sbin/tinyproxy
  21075   2-15:05:35 [kstriped]
  21082   2-15:05:35 [ksnapd]
  17275 373-00:07:49 /usr/sbin/httpd

Notice the time output now. The first two processes have hours, minutes, and seconds. The next three processes reveal the number of days they've been alive (with a dash between the day and hour). This is something I can work with. But how do we know the start date of the process? Fortunately, the date command helps me there:

  me@mybox:~$ date -d '-373 days'
  Mon Apr 21 09:42:34 EDT 2008

And most importantly, I can capture the date object in a shell script and use it if I need to.

Method #2: Start time

This is a variation of the above command. It shows the actual start date using the lstart parameter:

  me@mybox:~$ ps -eo pid,lstart,cmd
  20571 Wed Apr 29 08:22:26 2009 /usr/sbin/tinyproxy
  20572 Wed Apr 29 08:22:26 2009 /usr/sbin/tinyproxy
  21075 Sun Apr 26 18:25:01 2009 [kstriped]
  21082 Sun Apr 26 18:25:01 2009 [ksnapd]
  17275 Mon Apr 21 09:24:09 2008 /usr/sbin/httpd

Although this isn't as script-friendly as the previous method, its definitely more human-friendly. :-)