我有这个脚本来比较cpuload
是否大于限制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
现在,即使价值低于限额,我也会收到电子邮件(3 > 10)
。
哪里有问题?
我尝试了条件语法的组合,但有时有效,有时无效...我有点困惑。
谢谢。
更新
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")
在第一种情况下,电子邮件仍在发送。
更新2
这有效。但我不确定为什么。:/
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
答案1
您在此处的方法由于多种原因而注定会失败。
首先,即使你获得了算术比较的正确语法,即:
[ $cpuload -gt $limit ]
(兼容 POSIX shell)或
[[ $cpuload -gt $limit ]]
(bash / ksh 扩展测试)或
(( cpuload > limit ))
bash shell 仅支持整数运算,因此您需要先去掉末尾的小数,同时注意您所在语言环境的数字表示形式,正如 HuHa 所提到的。
请注意,当你使用[[ $cpuload > $limit ]]
它时是在 bash 中,这是语法上有效的比较,但它会“奇怪”地工作,因为它按字典顺序逐个字符比较 RHS 和 LHS。特别是,
$ [[ 3.0 > 10.0 ]] && echo greater || echo not greater
greater
因为 character3
在字典中大于 character 1
;而
$ [[ 03.0 > 10.0 ]] && echo greater || echo not greater
not greater
因为字符0
在字典顺序上小于字符1
。最重要的是,如果你想在 bash 脚本中执行浮点运算,你将需要一个外部程序,例如bc
或awk
或perl
。1
其次,uptime
输出是为了方便人类阅读,而不是机器解析。具体来说,时间格式会根据实际正常运行时间而变化,例如:
(重启之前)
$ uptime
10:38:50 up 26 days, 12:33, 4 users, load average: 0.09, 0.04, 0.00
(重启后)
$ uptime
10:44:37 up 3 min, 1 user, load average: 0.17, 0.33, 0.16
尝试对其进行标记cut -d' '
特别脆弱,因为它依赖于每个字段的左填充量:例如,如果天数/小时数/分钟数/用户数从个位数变为两位数,它就会失败。
相反,我建议直接从/proc/loadavg
-读取平均负载,uptime
无论如何,您可以通过以下方式确认strace
:
$ strace -etrace=openat uptime 2>&1 | tail -n 3
openat(AT_FDCWD, "/proc/loadavg", O_RDONLY) = 4
12:49:38 up 2:08, 1 user, load average: 0.00, 0.01, 0.00
+++ exited with 0 +++
格式是简单的空格分隔的字段,您可以轻松解析和测试,awk
例如:
$ cat /proc/loadavg
0.52 0.58 0.59 1/5 3759
$ limit=10; awk -v limit="$limit" '$1+0 > limit {exit 1}' /proc/loadavg && echo "ok" || echo "overload"
ok
$ limit=0.5; awk -v limit="$limit" '$1+0 > limit {exit 1}' /proc/loadavg && echo "ok" || echo "overload"
overload
笔记:
- 当然,你可以切换到做支持非整数运算,例如
ksh
或zsh
。