预期一元运算符

预期一元运算符
#!/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 可能的原因是什么

答案1

问题

问题是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}')

答案2

你的线路

top -b -n1 | awk '/^Cpu/ {print $2}' | cut -d. -f1

是错误的。首先,您要求 AWK 查找以 开头的行Cpu,而实际上它以 开头%Cpu

其次,你不需要cutpart,你可以awk直接使用:

$ top -b -n1 | awk '/^%Cpu/ {gsub(/\./," ");print $2}'                                             
31

将来,您可以在set -x脚本顶部的#!/bin/bash行后使用 来调试脚本。此外,使用https://www.shellcheck.net/检查 shell 脚本的语法

相关内容