I have this script to compare cpuload
is greater then limit 10
.
#!/bin/bash
cpuload=$(uptime | cut -d' ' -f 13 | sed '$ s/.$//')
limit=10
echo
echo "cpuload = $cpuload, limit = $limit"
echo
[[ $cpuload > $limit ]] && echo | mail -s "cpuload $cpuload is higher than $limit!" EMAIL
Now, I am receiving emails even if value is lower than limit (3 > 10)
.
Where is the problem?
I tried combinations with condition syntax, but sometimes it is working, sometimes not... I am little confused.
Thanks.
UPDATE
cpu_load=$(uptime | cut -d' ' -f 13 | sed '$ s/.$//')
limit=1
send_email(){
echo | mail -s "makroczsk, cpuload $cpu_load is higher than limit $limit!" $email_to
}
echo "cpuload = $cpu_load (${cpu_load%%.*}), limit = $limit"
[[ (( ${cpu_load%%.*} > $limit )) ]] && send_email
[[ ${cpu_load%%.*} -gt $limit ]] && send_email
cpuload = 3.10, limit = 10
./check-cpuload.sh: line 9: [[: 3.10: syntax error: invalid arithmetic operator (error token is ".10")
And in 1st case, emails are still coming.
UPDATE 2
This works. But I am not sure why. :/
cpu_load=$(uptime | cut -d' ' -f 13 | sed '$ s/.$//')
limit=1
send_email(){
echo | mail -s "makroczsk, cpuload $cpu_load is higher than limit $limit!" $email_to
}
echo "cpuload = $cpu_load (${cpu_load%%.*}), limit = $limit"
#[[ (( ${cpu_load%%.*} > $limit )) ]] && send_email
[[ ${cpu_load%%.*} -gt $limit ]] && send_email
Your approach here is doomed for a number of reasons.
First, even if you get the syntax correct for arithmetic comparison, i.e. either:
(POSIX shell compatible) or
(bash / ksh extended test) or
the bash shell only supports integer arithmetic, so you'd need to trim off any trailing decimal first, being mindful of your locale's numeric representation, as mentioned by HuHa.
Note that when you used
[[ $cpuload > $limit ]]
that is a syntactically valid comparison in bash, however it will work "strangely", since it compares the RHS and LHS lexicographically, character-by-character. In particular,because character
3
is lexicographically greater than character1
; whereasbecause character
0
is lexicographically less than character1
. The bottom line is that if you want to do floating point arithmetic in a bash script, you will need an external program such asbc
orawk
orperl
.1Second, the
uptime
output is intended for human readability, not machine parsing. In particular, the time format varies depending on the actual uptime, ex.:(before reboot)
(after reboot)
Attempting to tokenize it with
cut -d' '
is especially fragile, since it relies on exactly how much left-padding each of the fields has: it will fail if the number of days / hours / minutes / users rolls over from single to double digits for example.Instead, I'd suggest reading the load average directly from
/proc/loadavg
- which is whereuptime
gets it from anyhow, as you can confirm withstrace
:The format is simple whitespace separated fields that you can easily parse and test with
awk
for example:Notes:
ksh
orzsh
.