タスク:
(例えば0.23)のような10進数形式で上からロード平均をstdout
詳細:
このスクリプトを解析してChefのインスペックに変換し、その結果が何かよりも大きいか小さいかを確認する必要があります。次に例を示します。
describe command("top -b -n 1 | awk '/load average/ { sub(/,/,\".\",$10); printf \"%f\n\",$10}'") do
its("stdout") { should eq 0.00 }
end
この例は ""を返します
しかし、今考えると、/proc/loadavg
のファイルと比較できます
進捗状況
このリソースを使用: 負荷平均を上部で取得
このコマンドを使用すると、出力を適切に表現できますが、これは文字列であり、数学的な操作を実行できません。
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%s\n", $10}'
0,63,
しかし、printfをdecimal/floatに変更しようとすると、エラーが発生します。
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%f\n", $10}'
0.000000
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%d\n", $10}'
0
エコーできません、カットしてみました、悪い考え-機能していません:
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%s\n", $10}'|cut -c1-4
0,15
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ { printf "%s\n", $10}'|$((cut -c1-4))
-4: command not found
別の試み:
martin@martinv-pc:~$ top -b -n 1 | awk '/load average/ BEGIN { printf "%.f\n", $10};'
awk: line 1: syntax error at or near BEGIN
質問:
文字列値をdecimal/float/integerに変換するにはどうすればよいですか?
ps -o user,rss
出力:
[vagrant@localhost ~]$ ps -o user,rss
USER RSS
vagrant 736
vagrant 1080
タスク:
次のような10進形式で負荷平均を上からsdoutします(例:0.23)
ソリューション:
top -b -n 1 | Perl -lane 'print "$1.$2" if /load average: (\d+)[,.](\d+)/'
注:
これにより、1mの負荷平均が取得されます。これはあなたが望んでいることのように見えますが、明確に述べる必要があります。必要に応じて、コードを簡単に変更して、5分または15分、あるいは3つすべての平均負荷を取得できます。
@ terdon で指摘されているように、この場合、uptime
はtop
よりも優れた出発点になる可能性があります。
最初の2行の後に、obscurely結果で何をしたいかを記述します。実行したい後続のステップは、新しい質問の対象になるはずです。
Perlでは、数値は文字列に自動キャストされ、その逆も同様です。数値を表す文字列に対して数値演算を実行できます。例えばprint "$1.$2"+11.11
質問2:
この部分は、2番目の質問に関するもので、最初の質問とはまったく関係がないです。
OPにこの質問を個別に投稿することをお勧めします。
文字列値をdecimal/float/integerに変換するにはどうすればよいですか?
より良い記述: Chef 's InSpec を使用した文字列の数値比較の実行。
ソリューション:
文字列をto_i
またはto_f
を使用して数値形式に変換します。
例:
describe command("echo 1.00") do
its("stdout.to_f") { should be < 1.03 }
end
説明:
非常に合理的に、stdoutは文字列として扱われます。また、非常に合理的に、numeric比較では、2つの数値を...数値にする必要があります。幸い、変換は便利なRuby文字列メソッド:to_i
、to_f
、to_r
およびto_c
を使用して行うことができます。
From gawk:カンマ区切りでフォーマットされたフロートの合計 :
答えは--use-lc-numeric
gawkオプション。
--use-lc-numeric
これにより、gawkは入力データを解析するときにロケールの小数点文字を使用するようになります。 POSIX標準ではこの動作が必要ですが、-posixが有効な場合、gawkでも必要ですが、デフォルトでは従来の動作に従い、ピリオドが小数点文字ではないロケールでも、ピリオドを小数点として使用します。このオプションは、--posixオプションの完全な厳格な厳密性なしで、デフォルトの動作を上書きします。
あなたの場合、このコマンドはうまくいくはずです:
top -b -n 1 | awk --use-lc-numeric '/load average/ { printf "%f\n", $10}'
おそらく、小数点記号として,
を持つロケールを使用しています。次のいずれかの方法を試すことができます。
top
にはCロケールを使用します。
LC_ALL=C top -b -n 1 | awk '/load average/ { printf "%f\n",$10}'
これは、ピリオドとコンマの問題に対処するだけでなく、load average
のようなテキストがユーザーの言語に翻訳される問題も回避します。
コンマをドットに置き換えます。
top -b -n 1 | awk '/load average/ { sub(/,/,".",$10); printf "%f\n",$10}'
GNU awk
の場合、--use-lc-numeric
フラグを使用 @ Leoが推奨 またはPOSIXLY_CORRECT=1 awk
を使用。
または One True awk のようなPOSIX準拠のawk
実装を使用して、デフォルトでロケールルールに従って数値を解析および出力する必要があります。
負荷平均を取得するためのより移植性の高いコマンドはuptime
です。
あなたの問題は、抽出されたフィールドが小数点記号としてコンマを使用していて、awkが浮動小数点がドットを使用することを期待していることです。
これはあなたの問題を再現します:
$ LC_ALL=de_DE top -bn 1 | awk 'NR==1'
top - 08:37:07 up 1 day, 10:22, 5 users, load average: 0,17, 0,24, 0,26
ご覧のとおり、数値は小数点記号としてカンマを使用しています。次のようなものが必要です。
$ LC_ALL=en_US top -bn 1 | awk 'NR==1'
top - 08:38:28 up 1 day, 10:23, 5 users, load average: 0.56, 0.34, 0.30
しかし、それはインストールされているロケールに依存します(locale -a
)をシステムにインストールします。 C
ロケールは常に利用可能です。
$ LC_ALL=C top -bn 1 | awk 'NR==1'
top - 08:40:35 up 1 day, 10:25, 5 users, load average: 0.50, 0.39, 0.31
しかし、topを使用して最初の行のみを抽出するのはやり過ぎです。稼働時間の改善:
$ LC_ALL=C uptime
08:42:08 up 1 day, 10:27, 5 users, load average: 0.35, 0.37, 0.31
しかし、さらに良いのは、/proc/loadavg
ファイル
$ cat /proc/loadavg
0.29 0.34 0.30 1/468 15084
ちなみに、これはロケールの影響を受けません。最初の数値は1分の負荷平均です。それを選択して、任意の形式で印刷します。
$ awk '{printf( "%s\n %f\n %d\n", $1, $1, $1 )}' /proc/loadavg
0.35
0.350000
0
1、5、15分の負荷平均の使用:
$ awk '{printf( "%7.3f %7.3f %5.2f\n", $1, $2, $3 )}' /proc/loadavg
0.150 0.340 0.33