【问题标题】:How to monitor CPU usage automatically and return results when it reaches a threshold如何自动监控 CPU 使用率并在达到阈值时返回结果
【发布时间】:2017-12-14 04:25:57
【问题描述】:
我是 shell 脚本的新手,我想编写一个脚本来监控 CPU 使用率,如果 CPU 使用率达到阈值,它应该通过 top 命令打印 CPU 使用率,这是我的脚本,它给了我错误错误号并且不在日志文件中存储任何值
while sleep 1;do if [ "$(top -n1 | grep -i ^cpu | awk '{print $2}')">>sy.log - ge "$Threshold" ]; then echo "$(top -n1)">>sys.log;fi;done
【问题讨论】:
标签:
linux
bash
shell
ubuntu
【解决方案1】:
您的脚本必须缩进并存储到文件中,特别是如果您是 shell 新手!
#!/bin/sh
while sleep 1
do
if [ "$(top -n1 | grep -i ^cpu | awk '{print $2}')">>sy.log - ge "$Threshold" ]
then
echo "$(top -n1)" >> sys.log
fi
done
你的情况看起来有点奇怪。它可能有效,但看起来非常复杂。将中间结果存储在变量中,并对其进行评估。
然后,您将立即在“-ge”上看到语法错误。
出于安全原因,您必须将日志文件存储在绝对路径中。使用变量来简化阅读。
#!/bin/sh
LOGFILE=/absolute_path/sy.log
WHOLEFILE=/absolute_path/sys.log
Thresold=80
while sleep 1
do
TOP="$(top -n1)"
CPU="$(echo $TOP | grep -i ^cpu | awk '{print $2}')"
echo $CPU >> $LOGFILE
if [ "$CPU" -ge "$Threshold" ] ; then
echo "$TOP" >> $WHOLEFILE
fi
done
【解决方案2】:
你有几个错误。
- 如果您通过重定向将输出写入
sy.log,则该输出不再可用于shell。您可以通过 tee 解决此问题。
-
-ge 之前的破折号后面不能跟空格。
另外,一些风格上的评论:
-
grep x | awk '{y}' 是 useless use of grep;这可以更有用且更经济(以及更优雅)重写为awk '/x/{y}'
-
echo "$(command)" 是 useless use of echo——不是破坏交易,但您只需要 command;无需捕获它打印到标准输出的内容,这样您就可以将该文本打印到标准输出。
- 如果您无论如何要捕获
top -n 1 的输出,则实际上不需要运行两次。
补充说明:
- 如果您知道要提取的字段的大小写,也许您不需要不区分大小写进行搜索。 (我找不到
top 的版本,它在第二个字段中打印带有负载的 CPU 前缀——表达式真的正确吗?)
- shell 仅支持整数运算。这是一个错误吗?也许您想使用 Awk(支持浮点)来执行比较?这也允许进行适度棘手的重构。如果比较失败,我们让 Awk 输出退出代码 1,并将其用作
if 的条件。
#!/bin/sh
while sleep 1
do
if top=$(top -n 1 |
awk -v thres="$Threshold" '1; # print every line
tolower($1) ~ /^cpu/ { print $2 >>"sy.log";
exitcode = ($2 >= thres ? 0 : 1) }
END { exit exitcode }')
then
echo "$top" >>sys.log
fi
done
您真的是要拥有两个名称几乎相同的日志文件,还是拼写错误?在日志中包含时间戳可能有助于故障排除和实际使用日志文件。