patternbashMinor
Checking percentage of free memory using top and awk
Viewed 0 times
topfreeawkcheckingusingmemoryandpercentage
Problem
The following Awk code was created in order to verify if free memory from the top command is less than 20% of the total.
I've noticed that I actually do not need the
But on the other hand, I could not run the Awk as:
My current code is:
I have a feeling that this code is ugly because of the
I've noticed that I actually do not need the
top -n1 | grep Mem |, because the FREEM and TOTALM parameters are inside the third awk line.But on the other hand, I could not run the Awk as:
awk -v FREEM=$FREE_ME MORY -v TOTALM=$TOTAL_MEMORY '{per=int(FREEM)/int(TOTALM)*100; if(per<=20) print "FAIL" ; else print "OK"}'My current code is:
TOTAL_MEMORY=` top -b -n1 | grep Mem: | awk '{print $2}' `
FREE_MEMORY=` top -n1 | awk -v RS="[, ]" '/free/{print a}{a=$0}' | head -1 `
top -n1 | grep Mem | awk -v FREEM=$FREE_MEMORY -v TOTALM=$TOTAL_MEMORY '{per=int(FREEM)/int(TOTALM)*100; if(per<=20) print "FAIL" ; else print "OK"}'I have a feeling that this code is ugly because of the
top -n1 | grep Mem |. Are there any suggestions on running the awk without it?Solution
On my test system, the output of
I suppose yours is similar.
From your code it looks like you are extracting the values from the
in this example
Those values are in the 2nd and 6th column (in Awk terms), so you can get them easily in one command with:
Now it's easy to add the percentage calculation and print the result:
Some additional points of interest:
UPDATE
If you the position of free memory can be in different columns depending on the system, you have (at least) 2 options to work around that:
-
If you can know the position in advance (by detecting based on the system / runtime environment), you could pass that in as a variable, for example:
-
Or, you could use regular expressions, for example:
top -b -n1 | head looks like this:top - 09:33:08 up 9 days, 23:07, 7 users, load average: 0.01, 0.10, 0.13
Tasks: 125 total, 1 running, 124 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2%us, 0.0%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 4054892k total, 3938964k used, 115928k free, 56k buffers
Swap: 10485756k total, 536176k used, 9949580k free, 438836k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 10548 36 8 S 0 0.0 0:02.69 init
2 root 20 0 0 0 0 S 0 0.0 0:00.06 kthreadd
3 root 20 0 0 0 0 S 0 0.0 0:01.22 ksoftirqd/0I suppose yours is similar.
From your code it looks like you are extracting the values from the
Mem: line,in this example
4054892k and 115928k.Those values are in the 2nd and 6th column (in Awk terms), so you can get them easily in one command with:
top -b -n1 | awk '/^Mem:/ {total=int($2); free=int($6);}'Now it's easy to add the percentage calculation and print the result:
top -b -n1 | awk '/^Mem:/ {total = $2; free = $6; per = free / total * 100; print per <= 20 ? "FAIL" : "OK"; exit}'Some additional points of interest:
- After printing, we
exitto stop processing unnecessarily the rest of the output coming fromtop
- The ternary operator
?:can simplify the printing, no need for an if-else
- I dropped the
int(...)calls, as Awk seems to drop the trailing non-numeric values anyway
- The pattern
/^Mem:/is more strict than in the original code, just to be safe
UPDATE
If you the position of free memory can be in different columns depending on the system, you have (at least) 2 options to work around that:
-
If you can know the position in advance (by detecting based on the system / runtime environment), you could pass that in as a variable, for example:
i=6; top -b -n1 | awk -v i=$i '/^Mem:/ {total = $2; free = $i; per = free / total * 100; print per <= 20 ? "FAIL" : "OK"; exit}'-
Or, you could use regular expressions, for example:
top -b -n1 | awk '/^Mem:/ {total = $2; match($0, /[0-9]+[a-z] free/); free = substr($0, RSTART); per = free / total * 100; print per <= 20 ? "FAIL" : "OK"; exit}'Code Snippets
top - 09:33:08 up 9 days, 23:07, 7 users, load average: 0.01, 0.10, 0.13
Tasks: 125 total, 1 running, 124 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2%us, 0.0%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 4054892k total, 3938964k used, 115928k free, 56k buffers
Swap: 10485756k total, 536176k used, 9949580k free, 438836k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 10548 36 8 S 0 0.0 0:02.69 init
2 root 20 0 0 0 0 S 0 0.0 0:00.06 kthreadd
3 root 20 0 0 0 0 S 0 0.0 0:01.22 ksoftirqd/0top -b -n1 | awk '/^Mem:/ {total=int($2); free=int($6);}'top -b -n1 | awk '/^Mem:/ {total = $2; free = $6; per = free / total * 100; print per <= 20 ? "FAIL" : "OK"; exit}'i=6; top -b -n1 | awk -v i=$i '/^Mem:/ {total = $2; free = $i; per = free / total * 100; print per <= 20 ? "FAIL" : "OK"; exit}'top -b -n1 | awk '/^Mem:/ {total = $2; match($0, /[0-9]+[a-z] free/); free = substr($0, RSTART); per = free / total * 100; print per <= 20 ? "FAIL" : "OK"; exit}'Context
StackExchange Code Review Q#64485, answer score: 5
Revisions (0)
No revisions yet.