#!/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
。
其次,你不需要cut
part,你可以awk
直接使用:
$ top -b -n1 | awk '/^%Cpu/ {gsub(/\./," ");print $2}'
31
将来,您可以在set -x
脚本顶部的#!/bin/bash
行后使用 来调试脚本。此外,使用https://www.shellcheck.net/检查 shell 脚本的语法