0

I am trying to calculate the CPU load of a processor using the steps found here. I managed to do this:

cat /proc/stat | head -n 1 | awk '{print ($5+$6, $2+$3+$4+$7+$8+$9)}' | awk '{print($1,$1+$2)}' 

This gives me the values I need. However, I need to calculate the same values a second later and then use both of these results to calculate the final load. That means, that I need to do something like this:

cat /proc/stat | calculate something | awk '{print($1,$1+$2)}' ; sleep for a second; calculate again; use both of the results 

Is there a way for me to save the variables $1 and $1+$2 in the first awk call, so that I can use them later? I cannot use a bash script, it needs to be done in a command line.

2
  • 1
    bash script, it needs to be done in a command line Command line is bash, it's the same. hat I need to do something So do exactly that. a=$(....); sleep 1; b=$(...); echo use $a and $b. Commented Feb 26, 2022 at 11:45
  • can you expand on your comment: it needs to be done in a command line.? everytime you need to perform this operation ... are you going to manually type it at the command prompt? wouldn't it make more sense to place it in a script that can be executed repeatedly (without the need to do all that typing, or to introduce syntax/logic errors with manual typing)? even placing the logic into a function (a type of 'script'; see EdMorton's answer) would be of use Commented Feb 26, 2022 at 15:29

2 Answers 2

3

You don't need to piece together separate calls to tools in a pipeline for your existing command. This:

cat /proc/stat | head -n 1 | awk '{print ($5+$6, $2+$3+$4+$7+$8+$9)}' | awk '{print($1,$1+$2)}' 

can be rewritten as this:

awk 'NR==1{x=$5+$6; print x, x+$2+$3+$4+$7+$8+$9; exit}' /proc/stat 

It sounds like what you might want to do is something like:

foo() { awk 'NR==1{x=$5+$6; print x, x+$2+$3+$4+$7+$8+$9; exit}' /proc/stat; } { foo; sleep 1; foo; } | awk 'NR==1{ p1=$1; p2=$2; next } { use p1, $1, p2, and $2 }' 

If you can't do whatever it is you're trying to do given that information then edit your question to provide clearer requirements and some concise, testable, truly representative sample input/output.

Sign up to request clarification or add additional context in comments.

Comments

1

A simple solution would be to create the complete input first and process it with awk next. We first define the cpuLoad bash function to capture two CPU loads with a 1 second interval:

$ cpuLoad () { head -n 1 /proc/stat sleep 1 head -n 1 /proc/stat } $ cpuLoad cpu 8481582 17390 3183770 873720681 403491 0 708461 0 0 0 cpu 8481582 17390 3183774 873721078 403491 0 708461 0 0 0 

Then we can feed an awk script that implements the exact algorithm of the accepted answer you cite:

$ cpuLoad | awk '{ Idle = $5+$6 NonIdle = $2+$3+$4+$7+$8+$9 Total = Idle + NonIdle totald = Total - PrevTotal idled = Idle - PrevIdle PrevTotal = Total PrevIdle = Idle } END { CPU_Percentage = 100.0 * (totald - idled) / totald print CPU_Percentage }' 4.987531 

But we can simplify a lot:

$ cpuLoad | awk '{ totald = $2+$3+$4+$5+$6+$7+$8+$9 - totald idled = $5+$6 - idled } END { print 100.0 * (totald - idled) / totald }' 0.501253 

And finally, we can encapsulate all this in the bash function:

$ cpuLoad () { { head -n 1 /proc/stat; sleep 1; head -n 1 /proc/stat; } | awk '{t = $2+$3+$4+$5+$6+$7+$8+$9 - t; i = $5+$6 - i} END {print 100.0 * (t - i) / t}' } $ cpuLoad 0.750000 

1 Comment

That makes a lot of sense. I was too focused on helping the OP implement the solution they asked for and didn't bother to think if there was a better solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.