Getting CPU time of a running process turns out to be not-so-easy. You’d think there’d just be a utility you can run - Fetch me the elapsed CPU time of this process! - and… well, okay, there actually is. It’s called ps
. You run ps h -o time -C PROC_NAME
, and sum them up in your bash script, and all is fine and dandy, until your boss comes over and asks you why all your CPU times are in seconds, and could you please make it more precise.
So you go do some hard research on the internet, and you get a bunch of stuff about CPU usage and things in C and some other things, and not much on how to get CPU time in Bash. Eventually, you do happen upon some helpful posts - Just use /proc/pid/stats! they say, followed by a caveat that the times recorded in the file are in clock ticks instead of normal person time. When you ask them about how to get how many clock ticks are in a second, they mumble something about C and sysconf(_SC_CLK_TCK)
and run off, never to be heard from again.
Okay, well, that’s fine, you can write a C program that gets compiled which outputs this weird thing. Except your script should be cross-platform (if not cross-OS), and you’ll need to compile this program on every system you want to run this script on and suddenly your script needs a configure script for some goshdarn reason, and it needs make, and nevermind let’s go back to google.
Eventually, after ritually slaughtering a cow, solving a riddle posed by three sisters at a bar, and sifting through the long-dead remains of a city, you unearth a helpful note:
@Manish I believe you can execute the following in the shell: `getconf CLK_TCK`. – Vilhelm Gray
Thank you, Vilhelm Gray. You are truly a hero.
# Finds CPU time of all processes named $1.
# Disclaimer: I am not a shell programmer.
getcputime() {
local proc=$1
local clk_tck=$(getconf CLK_TCK)
local cputime=0
local pids=$(pidof $proc)
for pid in $pids;
do
local stats=$(cat "/proc/$pid/stat")
local statarr=($stats)
local utime=${statarr[13]}
local stime=${statarr[14]}
cputime=$(bc <<< "scale=3; $cputime + $utime / $clk_tck + $stime / $clk_tck")
done
echo $cputime
}
And I’m sure someone, someday, will knock on my door, punch me in the head, and leave a comment to the effect that there was a single command to do this all along, you idiot.
EDIT: Actually, no need for that, as I have found it already. Turns out top
has a batch mode, and it displays CPU time in hundredths of a second. All you really need to do is run top -bn 1
and parse that. I’ll just go punch myself in the head now…