抽象的な:

抽象的な:

レモンバーの設定を試して設定するには、このガイドに従っています。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

awkreadすべての '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%を出力するわけではありません(GNUは環境とawk同様にPOSIXモードでのみこれを行います)。小数点の下をピリオド/ドットに強制変換する$POSIXLY_CORRECTために使用されます。LC_ALL=C awk...

少数の部分がまったく必要ない場合に%.1f変更します。%.0fこれは丸められます最近整数。%d少数の部分を切り捨てるには(99.999は100%ではなく99%です)、別の方法を使用してください。

変更されていないと見なされる以前のバージョンで作業しますread t f <<< `grep -E 'Mem(Total|Free)' /proc/meminfo |awk '{print $2}'`bash$IFS

では、cmd <<< `code`出力を文字(デフォルトでは改行を含む)に分割しbash、コマンドを標準入力として入力する前に、最初の文字(デフォルトでは空白)に関連付けるために使用されます。したがって、あなたの場合、出力の2行は期待どおりに1行に2単語で提供されます。この驚くべき動作(bash-4.4の元の実装とは異なります)はbash-4.4で修正されました。code$IFS$IFSawkread t fzsh

上記と上記bash-4.4は必要です{ read t; read f; } <<< "$(awk...)"$(...)bash-4.3以前のバージョンでも機能するためにここに引用符を追加し、デフォルト値はまだ仮定されています$IFS)。

答え2

抽象的な:

移植可能、1行、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

このエラーを回避する1つの方法は、デフォルト値を設定することです。

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

値が1つしかない理由は、読み取りが別の行にある値を取得するためです(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 )
                    }
                   '

1行にprintfを使用すると、次のようになります。

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

より速く実行してシェルを使用するには(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

コマンドで読み取った文字列にはread1つのフィールドのみが含まれ、そのうち2つは同時に埋め込まれ、変数になるとt予想されます。f

| tr '\n' ' 'この問題はコマンドの後に追加することで解決できますawk

しかし、次のように単純化することをお勧めします。

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

関連情報