Bash 脚本 "integer expression expected" ,(在 bash 中浮动)将部分替换为 awk



我写了一个小bash脚本来检查我的内存使用情况,并在内存使用率过高时警告我。

现在我的问题是,我想保持浮动价值,而不是仅仅削减它。但我做不到。

我更喜欢awk而不是其他任何东西,因为它已经预装在许多系统上,而且我已经在脚本中使用了它。

#!/bin/bash
#define what values are too high (%)
inacceptableRAM="90"
#check RAM %
RAM=`free | grep Mem | awk '{print $3/$2 * 100.0}'`
#send Alarm for RAM
if [ $RAM -ge $inacceptableRAM ] ; then
echo Alarm RAM usage is @$RAM"
fi

那么如何使用awk替换我的if-ge呢?我认为它应该看起来像:awk'$RAM>=$不可接受的RAM但是我需要做些什么才能使它在bash脚本中工作呢?

由于您正在与整数进行比较,因此在比较时可以去掉小数部分:

if [ "${RAM%.*}" -ge "$inacceptableRAM" ] ; then

如果您想完全在awk中完成,唯一棘手的事情是必须使用-v var=valueinacceptableRAMshell变量转换为awk变量:

free | awk -v limit="$inacceptableRAM" '/Mem/ {ram=$3/$2*100; if (ram>=limit) print ram}'

请注意,我在awk脚本中使用/Mem/来有效地替换grep命令。从grepawk的管道几乎从不需要,因为您可以在awk中完成所有操作。

其他建议:使用$( )而不是backticks进行命令替换(请参阅BashFAQ#82(,并使用小写或混合大小写的变量名(例如ram而不是RAM(,以避免意外使用具有特殊含义的众多全大写名称中的一个(请参阅此答案(。

awk的替代品是bc,类似于:

#!/usr/bin/env bash
#define what values are too high (%)
inacceptableRAM="90"
#check RAM %
ram=$(free | awk '/Mem/{print $3/$2 * 100.0}')
#send Alarm for RAM
if (( $(bc <<< "$ram > $inacceptableRAM") )) ; then
echo "Alarm RAM usage is @$ram"
fi

您试图在shell中执行太多操作。shell是一种操作文件、处理对其他工具的调用并对其排序的工具。创建shell的人也为shell创建了一个工具,用来调用它来操作文本

#!/usr/bin/env bash
free |
awk '
BEGIN {
#define what values are too high (%)
unacceptableRam = 90
}
/Mem/ {
#check RAM %
ram = ( $2 ? $3 / $2 * 100 : 0 )
#send Alarm for RAM
if ( ram >= unacceptableRam ) {
print "Alarm RAM usage is @" ram
}
}
'

如果是时候"升级";到一种支持浮点运算等功能的适当编程语言。Bash和shell脚本很好,但它很快就会遇到限制。甚至谷歌的外壳风格指南也建议在事情变得复杂时更改语言。您很可能只需要多写几行代码就可以让Python脚本完成Bash脚本所做的工作。

也就是说,我对依赖Bash感到非常内疚,即使我可能不应该这样做:(

我最近想在Bash脚本中计算浮点平均值,并决定将该任务委托给Python子进程,而不是完全切换到Python。我选择Python是因为它几乎和Bash一样无处不在,易于阅读,而且可扩展。我考虑过bc,但担心它可能不会安装在所有系统上。我没有考虑awk,因为尽管它是一个很棒的工具,但它的语法往往是不透明和晦涩的。Python可能比bcawk慢,但我真的不在乎性能的差异。如果我真的在乎,那将是强有力的证据,我应该用表演语言重写整个脚本。

对于您的用例,Jetchill建议使用bc <<< "$ram > $inacceptableRAM"可能就足够了,因为Python等效程序更为冗长,但对于更复杂的东西,Python可能是一个不错的选择。

最新更新