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. :-)