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

Bash Script "integer expression expected" , (floats in bash) replace part with awk

我写了一些 bash-脚本来检查我的内存使用情况并在它太高时警告我。

现在我的问题是,我想保留浮动值而不是将其删除。但是我做不到..

我更喜欢 awk,因为它已预装在许多系统上,而且我已经在脚本中使用了它。

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

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

awk 的替代方法是 bc ,例如:

#!/usr/bin/env bash

#define what values are too high (%)
inacceptableRAM="90"

#check RAM %
ram=$(free | awk '/Mem/{print / * 100.0}')

#send Alarm for RAM
if (( $(bc <<< "$ram > $inacceptableRAM") )) ; then
   echo "Alarm RAM usage is @$ram"
fi

因为你是在与一个整数进行比较,所以你可以在比较时只trim去掉小数部分:

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

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

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

请注意,我在 awk 脚本中使用 /Mem/ 来有效地替换 grep 命令。从 grepawk 的管道几乎从来没有必要,因为你可以 just do it all in awk.

其他建议:使用 $( ) 代替反引号进行命令替换(参见 BashFAQ #82), and use lower- or mixed-case variable names (e.g. ram instead of RAM) to avoid accidentally using one of the many all-caps names that have special meanings (see this answer)。

您在 shell 中尝试做的事情太多了。 shell 是一种用于操作文件以及处理和排序对其他工具的调用的工具。创建 shell 的人还为 shell 创建了调用来操作文本的工具是 awk:

#!/usr/bin/env bash

free |
awk '
    BEGIN {
        #define what values are too high (%)
        unacceptableRam = 90
    }
    /Mem/ {
        #check RAM %
        ram = (  ?  /  * 100 : 0 )

        #send Alarm for RAM
        if ( ram >= unacceptableRam ) {
            print "Alarm RAM usage is @" ram
        }
    }
'

如果是时候“升级”到支持浮点运算等功能的适当编程语言,则值得考虑。 Bash 和 shell 脚本很棒,但它很快就会遇到限制。即使 Google 的 Shell Style Guide 也建议在事情变得复杂时更换语言。很可能你可以得到一个 Python 脚本来完成你的 Bash 脚本正在做的事情,只需要多几行代码。

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

我最近想计算一个 floating point average in a Bash script 并决定委托给一个 Python 子进程 只是 来完成该任务,而不是完全切换到 Python。我选择 Python 是因为它几乎与 Bash 一样普遍,易于阅读且可扩展。我考虑过 bc 但担心它可能不会安装在所有系统上。我没有考虑 awk,因为尽管它是一个很棒的工具,但它的语法通常是晦涩难懂的。 Python 可能比 bcawk 慢,但我真的不关心这种增量性能差异。如果我确实关心这将是强有力的证据,我应该用一种高性能语言重写整个脚本。

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