linuxshellawkpostscript

ps start_time as timestamp


I'm currently using the ps command to monitor some processes. However, I would like to have the time output as a Unix timestamp.

The command I am using:

ps -eo class,s,user,pid,pcpu,stat,start_time,cputime,args --sort=class | \
  awk '$1 != "RR" && $1 != "FF" {print $0; next } 0'

Thanks!


Solution

  • Use etimes option (elapsed time since the process was started, in seconds) and awk's systime() function that returns the current timestamp in seconds.

    Suppose the 7th column is etimes, then the AWK expression should look like this:

    NR == 1 ? "TIMESTAMP" : systime() - $7
    

    Example:

    ps -eo class,s,user,pid,pcpu,stat,etimes,cputime,args --sort=class | awk \
      '$1 != "RR" && $1 != "FF" {print $0, NR == 1 ? "TIMESTAMP" : systime() - $7 }'
    

    Sample Output

    CLS S USER       PID %CPU STAT ELAPSED     TIME COMMAND TIMESTAMP
    TS  S root         1  0.0 Ss      1717 00:00:01 init [3] 1479001705
    TS  S root         2  0.0 S       1717 00:00:00 [kthreadd] 1479001705
    TS  S root         3  0.0 S       1717 00:00:00 [ksoftirqd/0] 1479001705
    

    If you want to replace the seventh column, you can just override the $7 variable: $7 = systime() - $7.

    If the result of the command is supposed to be parsed further, I would remove the headers with --no-headers option, e.g.:

    ps --no-headers -eo class,s,user,pid,pcpu,stat,etimes,cputime,args \
      --sort=class | awk '$1 != "RR" && $1 != "FF" { $7 = systime() - $7; print }'
    

    Sample Output

    TS S root 1 0.0 Ss 1479001705 00:00:01 init [3]
    TS S root 2 0.0 S 1479001705 00:00:00 [kthreadd]
    TS S root 3 0.0 S 1479001705 00:00:00 [ksoftirqd/0]
    

    Note, there is no need for the next statement in your script, since its purpose is to immediately stop processing the current record and go on to the next record, and there are no statements (pattern-action pairs) to skip at the end of the script.