Format the output of cputime for ps
This converts the first time to seconds:
ps -p $PROCID -o cputime,etimes | awk -F'[: ]+' '/:/ {t=$3+60*($2+60*$1); print t,$NF}'
As an example, the ps command produces:
$ ps -p 5403 -o cputime,etimes
TIME ELAPSED
01:33:38 1128931
The awk
command processes that and returns:
ps -p 5403 -o cputime,etimes | awk -F'[: ]+' '/:/ {t=$3+60*($2+60*$1); print t,$NF}'
5618 1128931
Explanation
-F'[: ]+'
This tells awk to treat both colons and spaces as field separators. This way, the hours, minutes, and seconds appear as separate fields.
/:/ {t=$3+60*($2+60*$1); print t,$NF}
The initial
/:/
restricts the code to working only on lines that include a colon. This removes the header lines. The number of seconds is calculated from hours, minutes, seconds viat=$3+60*($2+60*$1)
. The resulting value fort
is then printed along side with the elapsed time.
Handling days
If ps
produces days,hours,minutes,seconds, as in:
2-03:01:33
Then, use this code instead:
ps -p $PROCID -o cputime,etimes | awk -F'[-: ]+' '/:/ {t=$4+60*($3+60*($2+24*$1)); print t,$NF}'
If days may or may not be prepended to the output, then use this combination command:
ps -p $PROCID -o cputime,etimes | awk -F'[-: ]+' '/:/ && NF==5 { t=$4+60*($3+60*($2+24*$1)); print t,$NF} /:/ && NF==4 {t=$3+60*($2+60*$1); print t,$NF}'
If you don't want to bring awk in the game, a pure bash solution (t_str contains the formated string, t_sec the decoded time in seconds):
# Decode the CPU time format [dd-]hh:mm:ss.
IFS="-:" read c1 c2 c3 c4 <<< "$t_str"
if [ -n "$c4" ]
then
t_sec=$((10#$c4+60*(10#$c3+60*(10#$c2+24*10#$c1))))
else
t_sec=$((10#$c3+60*(10#$c2+60*10#$c1)))
fi