Home > Mobile >  Using variables in unix command line commands
Using variables in unix command line commands

Time:02-27

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.

CodePudding user response:

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.

CodePudding user response:

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
  • Related