抽象的:

抽象的:

我正在按照本指南尝试设置柠檬吧配置:http://blog.z3bra.org/2014/04/meeting-at-the-bar.html

现在,除了这一行之外,几乎所有内容都可以完美运行:

bc <<< "scale=2; 100 - $f / $t * 100" | cut -d. -f1

在这个函数中:

memused() {
    read t f <<< `grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`
    bc <<< "scale=2; 100 - $f / $t * 100" | cut -d. -f1
}

我收到以下错误(standard_in) 1: syntax error

现在据我所知,我应该在方程周围添加双括号,(())但我尝试了很多不同的安排,但没有任何方法可以修复错误。

答案1

awk可以在这里完成所有read's、cut's、grep's 和bc's 工作:

 awk -F': *' '
   $1 == "MemTotal" {t = $2}
   $1 == "MemFree" {f = $2}
   END {printf "%.1f%%\n", (t - f) * 100 / t}' /proc/meminfo

请注意,并非所有awk实现都会在使用逗号作为十进制基数的语言环境中输出 40,5% 而不是 40.5(GNUawk仅在 POSIX 模式下才这样做,就像$POSIXLY_CORRECT在环境中一样)。用于LC_ALL=C awk...强制小数基数为句点/点。

如果您根本不需要小数部分,请更改%.1f为。%.0f这将四舍五入到最近的整数。%d如果您想截断小数部分(99.999 的结果是 99%,而不是 100%),请使用替代方法。

read t f <<< `grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`将在bash假设未修改的旧版本中工作$IFS

在 中cmd <<< `code`,用于分割on 个字符(默认情况下包括换行符)的bash输出,并在作为标准输入输入命令之前将它们与第一个字符(默认情况下为空格)连接起来。因此,在您的情况下,的输出的这两行最终将按照 的预期作为一行上的两个单词提供。这种令人惊讶的行为(也与 中的原始实现不同)在 bash-4.4 中得到了修复。code$IFS$IFSawkread t fzsh

在上面bash-4.4和上面,你需要{ read t; read f; } <<< "$(awk...)"(这里添加引号,$(...)这样它也可以在 bash-4.3 及之前的版本中工作,仍然假设默认值$IFS)。

答案2

抽象的:

便携式,一行并使用 printf:

awk '/MemTotal/{t=$2}; /MemFree/{f=$2}; END{printf("%d\n",(1-f/t)*100)}'

仅外壳(bash):

memused() { : # Print the (integer) value of % of free memory
            local ret ref a t f 
            ret='MemTotal:[ \t]*([0-9]+)';              # Regex for Total memory.
            ref='MemFree:[ \t]*([0-9]+)';               # Regex for Free  memory.
            a=$(</proc/meminfo)                         # Get meminfo in var (a).
            [[ $a =~ $ret ]] && t="${BASH_REMATCH[1]}"  # Get Total memory.
            [[ $a =~ $ref ]] && f="${BASH_REMATCH[1]}"  # Get Free  memory.
            printf '%s\n' "$(( 100 - 100*f/t )) %"      # Print integer % value.
          }

描述

BC 抱怨的原因是它只得到一个 var。

重现:

$ t=150 ; f='' ; bc <<< "scale=2; 100 - $f / $t * 100"
(standard_in) 1: syntax error

避免该错误的一种方法是设置默认值:

$ t=150; f=''; bc <<< "scale=2; 100 - ${f:-0} / ${t:-0} * 100"
100

只有一个值的原因是读取是在单独的行中获取值(在 bash 4.4 中)。适用于所有 bash 版本的解决方案是使用-d ''

$ read -d '' t f <<< "`grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`"
$ echo "total=<$t>     free=<$f>"
total=<1922764>     free=<424360>

无论命令扩展是否被引用(应该如此),这都有效 "`grep … '`"

但没有理由打电话grep,,终于awk。一次调用 awk 即可完成这一切:bccut

</proc/meminfo awk '/MemTotal/{t=$2}
                    /MemFree/ {f=$2}
                    END{
                        print( (1-f/t)*100 )
                    }
                   '

在一行中并使用 printf:

awk '/MemTotal/{t=$2};/MemFree/{f=$2};END{printf("%d\n",(1-f/t)*100)}' </proc/meminfo

如果你想要运行得更快并且只使用 shell(尽管是 bash):

memused() {  : # Print the (integer) value of % of free memory
             local ret ref a t f 
             ret='MemTotal:[ \t]*([0-9]+)';              # Regex for Total memory.
             ref='MemFree:[ \t]*([0-9]+)';               # Regex for Free  memory.
             a=$(</proc/meminfo)                         # Get meminfo in var (a).
             [[ $a =~ $ret ]] && t="${BASH_REMATCH[1]}"  # Get Total memory.
             [[ $a =~ $ref ]] && f="${BASH_REMATCH[1]}"  # Get Free  memory.
             printf '%s\n' "$(( 100 - 100*f/t )) %"      # Print integer % value.
   }

答案3

命令读取的字符串read仅包含 1 个字段,其中 2 个字段预计同时填充tf变量。

可以通过在命令| tr '\n' ' '后面添加来解决awk

但最好将其简化为:

read t f <<< $(awk '/MemTotal/{t=$2}/MemFree/{f=$2}END{print t,f}' /proc/meminfo)

相关内容