一元运算符预期
#!/bin/bash SUBJECT="WARNING CPU USAGE HIGH" TO=gmail id MESSAGE=/tmp/messages echo "#######################" > $MESSAGE echo "CPU statistics as follows.." >> $MESSAGE mpstat >> $MESSAGE echo "#######################" >> $MESSAGE CPU_USAGE=$(top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1) [ $CPU_USAGE -gt 85 ] && mail -s "$SUBJECT" "$TO" < $MESSAGE`
./cpu.sh: line 11: [: -gt: unary operator expected
可能是什么原因
问题
问题是CPU_USAGE
最终为空字符串。 这会导致一个问题:
[ $CPU_USAGE -gt 85 ]
在评估shell变量之后,上面变为:
[ -gt 85 ]
这失败了,因为-gt
之前的参数现在丢失了。
解决方案
要获得非空的CPU_USAGE
,我们需要替换:
CPU_USAGE=$(top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1)
有:
CPU_USAGE=$(top -b -n1 | awk '/^%Cpu/ {print $2}' | cut -d. -f1)
其中添加了%
。
引用
如上所述,当CPU_USAGE
为空且未加引号时,我们得到“一元运算符”错误:
$ CPU_USAGE=""; [ $CPU_USAGE -gt 85 ] && echo yes bash: [: -gt: unary operator expected
最好在这种情况下引用shell变量。 如果我们引用它,那么我们会得到一个不同的错误消息:
$ CPU_USAGE=""; [ "$CPU_USAGE" -gt 85 ] && echo yes bash: [: : integer expression expected
虽然我们仍然收到错误,但此错误消息至少提供了更多信息:它说$CPU_USAGE
不是数字。
简单化
不需要cut
过程。 我们可以替换:
CPU_USAGE=$(top -b -n1 | awk '/^%Cpu/ {print $2}' | cut -d. -f1)
有:
CPU_USAGE=$(top -b -n1 | awk -F'[ .]+' '/^%Cpu/ {print $2}')
你的路线
top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1
是不正确的。 首先,你要求AWK找到以Cpu
开头的行,而实际上它是从%Cpu
开始的。
其次,你不需要cut
部分。 你可以直接使用awk
:
$ top -b -n1 | awk '/^%Cpu/ {gsub(/\./," ");print $2}' 31
将来,您可以在#!/bin/bash
行之后使用脚本顶部的set -x
调试脚本。 另外,使用https://www.shellcheck.net/来检查shell脚本的语法