一元运算符预期

#!/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脚本的语法