web-dev-qa-db-ja.com

標準の* nixツールを使用してbashスクリプトですべてのコアのCPU使用率を取得する方法

dwmを使用してシステムの統計情報をxsetrootステータスバーに出力するbashスクリプトを書いています。すべてが期待どおりに機能します。現在欠けているのは、標準の*nixツールを使用して、システムのすべてのコアの現在の負荷を取得する簡単な方法です(4つのコアがあります)。これを行う方法がわかりません。 topを使用します。これまでにこのサイトで見つけた他のすべての投稿は、平均的な負荷を扱っています。これまでに誰かがこれをしたことがありますか?

コアごとに必要な主な理由は、プログラムが並列に記述したコード(たとえば、for eachループ)をプログラムが実行しているかどうかを確認する安価で大まかなツールがあるためです。

6
lord.garbage

/proc/statからコアあたりの平均使用量を計算しています

これまでに思いついた最善の解決策は、浮動小数点演算を説明するためにbcを使用することです。

# Calculate average cpu usage per core.
#      user  Nice system   idle iowait irq softirq steal guest guest_Nice
# cpu0 30404 2382   6277 554768   6061   0      19    0      0          0
A=($(sed -n '2,5p' /proc/stat))
# user         + Nice     + system   + idle
B0=$((${A[1]}  + ${A[2]}  + ${A[3]}  + ${A[4]}))
B1=$((${A[12]} + ${A[13]} + ${A[14]} + ${A[15]}))
B2=$((${A[23]} + ${A[24]} + ${A[25]} + ${A[26]}))
B3=$((${A[34]} + ${A[35]} + ${A[36]} + ${A[37]}))
sleep 2
# user         + Nice     + system   + idle
C=($(sed -n '2,5p' /proc/stat))
D0=$((${C[1]}  + ${C[2]}  + ${C[3]}  + ${C[4]}))
D1=$((${C[12]} + ${C[13]} + ${C[14]} + ${C[15]}))
D2=$((${C[23]} + ${C[24]} + ${C[25]} + ${C[26]}))
D3=$((${C[34]} + ${C[35]} + ${C[36]} + ${C[37]}))
# cpu usage per core
E0=$(echo "scale=1; (100 * ($B0 - $D0 - ${A[4]}   + ${C[4]})  / ($B0 - $D0))" | bc)
E1=$(echo "scale=1; (100 * ($B1 - $D1 - ${A[15]}  + ${C[15]}) / ($B1 - $D1))" | bc)
E2=$(echo "scale=1; (100 * ($B2 - $D2 - ${A[26]}  + ${C[26]}) / ($B2 - $D2))" | bc)
E3=$(echo "scale=1; (100 * ($B3 - $D3 - ${A[37]}  + ${C[37]}) / ($B3 - $D3))" | bc)
echo $E0
echo $E1
echo $E2
echo $E3

コアあたりの平均CPU使用量は/proc/statから直接計算できます(/proc/statを使用するためのヒントについては@mikeservにクレジットされます。):

# Here we make use of bash direct array assignment
A0=($(sed '2q;d' /proc/stat))
A1=($(sed '3q;d' /proc/stat))
A2=($(sed '4q;d' /proc/stat))
A3=($(sed '5q;d' /proc/stat))
# user         + Nice     + system   + idle
B0=$((${A0[1]} + ${A0[2]} + ${A0[3]} + ${A0[4]}))
B1=$((${A1[1]} + ${A1[2]} + ${A1[3]} + ${A1[4]}))
B2=$((${A2[1]} + ${A2[2]} + ${A2[3]} + ${A2[4]}))
B3=$((${A3[1]} + ${A3[2]} + ${A3[3]} + ${A3[4]}))
sleep 0.2
C0=($(sed '2q;d' /proc/stat))
C1=($(sed '3q;d' /proc/stat))
C2=($(sed '4q;d' /proc/stat))
C3=($(sed '5q;d' /proc/stat))
# user         + Nice     + system   + idle
D0=$((${C0[1]} + ${C0[2]} + ${C0[3]} + ${C0[4]}))
D1=$((${C1[1]} + ${C1[2]} + ${C1[3]} + ${C1[4]}))
D2=$((${C2[1]} + ${C2[2]} + ${C2[3]} + ${C2[4]}))
D3=$((${C3[1]} + ${C3[2]} + ${C3[3]} + ${C3[4]}))
# cpu usage per core
E0=$(((100 * (B0 - D0 - ${A0[4]} + ${C0[4]})) / (B0 - D0)))
E1=$(((100 * (B1 - D1 - ${A1[4]} + ${C1[4]})) / (B1 - D1)))
E2=$(((100 * (B2 - D2 - ${A2[4]} + ${C2[4]})) / (B2 - D2)))
E3=$(((100 * (B3 - D3 - ${A3[4]} + ${C3[4]})) / (B3 - D3)))
echo $E0
echo $E1
echo $E2
echo $E3

またはbashの直接配列割り当てを広範囲に使用することでさらに短くなります。

# Here we make use of bash direct array assignment by assigning line
# 2 to 4 to one array


A=($(sed -n '2,5p' /proc/stat))
# user         + Nice     + system   + idle
B0=$((${A[1]}  + ${A[2]}  + ${A[3]}  + ${A[4]}))
B1=$((${A[12]} + ${A[13]} + ${A[14]} + ${A[15]}))
B2=$((${A[23]} + ${A[24]} + ${A[25]} + ${A[26]}))
B3=$((${A[34]} + ${A[35]} + ${A[36]} + ${A[37]}))
sleep 0.2
# user         + Nice     + system   + idle
C=($(sed -n '2,5p' /proc/stat))
D0=$((${C[1]}  + ${C[2]}  + ${C[3]}  + ${C[4]}))
D1=$((${C[12]} + ${C[13]} + ${C[14]} + ${C[15]}))
D2=$((${C[23]} + ${C[24]} + ${C[25]} + ${C[26]}))
D3=$((${C[34]} + ${C[35]} + ${C[36]} + ${C[37]}))
# cpu usage per core
E0=$((100 * (B0 - D0 - ${A[4]}  + ${C[4]})  / (B0 - D0)))
E1=$((100 * (B1 - D1 - ${A[15]} + ${C[15]}) / (B1 - D1)))
E2=$((100 * (B2 - D2 - ${A[26]} + ${C[26]}) / (B2 - D2)))
E3=$((100 * (B3 - D3 - ${A[37]} + ${C[37]}) / (B3 - D3)))
echo $E0
echo $E1
echo $E2
echo $E3

topベースのソリューション

これは、topのみの追加のツールをインストールしなくても実現できます(後でこれを使用しました post 。)デフォルトでは、topは平均CPU負荷のみを表示します起動すると、1を押すとすべてのCPUが表示されます。 topのc​​pu出力をバッチ出力モードで使用するときに使用できるようにするには、これをtopの起動時にデフォルトの動作にする必要があります。これは、~/.toprcファイルを使用して行うことができます。幸いなことに、これは自動的に作成できます。topを開始して1を押し、Wを押すと、ホームフォルダーに~/.toprcファイルが生成されます。 top -bn 1 | grep -F '%Cpu'を実行すると、topがすべてのコアを出力するようになります。これで、これを機能させるために必要なものがすべて揃いました。必要なすべての情報は、topの出力となる配列の3列にあります。

問題は1つだけです。コアのCPU使用率が100%に達すると、コマンドが出力する配列によって、現在の負荷のある列が列3から列2に移動します。したがって、awk '{print $3}'を使用すると、us,が列3の出力として表示されます。それで問題がなければ、そのままにしておきます。そうでない場合は、awk印刷列2も使用できます。 :になります。これらの落とし穴をすべて回避するソリューションは次のとおりです。

top -bn 2 | grep -F '%Cpu' | tail -n 4 | gawk '{print $2 $3}' | tr -s '\n\:\,[:alpha:]' ' '

すべての改行\n,および文字[:alpha:]の出力を取り除き、1つの空白以外のすべて-sを削除します。

4
lord.garbage

これにより、各CPUの負荷が要素となるbash配列が作成されます。

loads=($(mpstat -P ALL 1 1 | awk '/Average:/ && $2 ~ /[0-9]/ {print $3}'))

Bash配列には0から始まる番号が付けられているため、2番目のCPUの負荷は次のように出力されます。

echo ${loads[1]}

これには、ユーティリティmpstatが必要です。これをdebianのようなシステムにインストールするには、以下を実行します。

apt-get install sysstat

使い方

mpstatによって生成されるやや冗長な出力は次のようになります。

$ mpstat -P ALL 1 1
Linux 3.2.0-4-AMD64 (MyMachine)     08/30/2014      _x86_64_        (2 CPU)

10:12:35 PM  CPU    %usr   %Nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
10:12:36 PM  all    1.49    0.00    1.49    0.00    0.00    0.00    0.00    0.00   97.01
10:12:36 PM    0    0.00    0.00    2.02    0.00    0.00    0.00    0.00    0.00   97.98
10:12:36 PM    1    1.96    0.00    1.96    0.00    0.00    0.00    0.00    0.00   96.08

Average:     CPU    %usr   %Nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
Average:     all    1.49    0.00    1.49    0.00    0.00    0.00    0.00    0.00   97.01
Average:       0    0.00    0.00    2.02    0.00    0.00    0.00    0.00    0.00   97.98
Average:       1    1.96    0.00    1.96    0.00    0.00    0.00    0.00    0.00   96.08

ここで、-P ALLmpstatにすべてのCPUと引数を表示するように指示し、引数1 1は1秒ごとに出力を出力し、最初の1秒後に停止するように指示します。

必要な値だけを選択するには、次のawkコマンドを使用します。

awk '/Average:/ && $2 ~ /[0-9]/ {print $3}'

これにより、最後の行(Average:で始まる行)のみが選択され、2番目の列が数値である行のみが選択されます。これらの行では、3番目の列(cpu load)が出力されます。

括弧を使用しているため、mpstat-awkパイプラインからの出力はbash配列にキャプチャされます。

8
John1024

私はこの解決策を思いつきました、そしてそれは私のために機能します。

echo print `top -n 1 | tr -s " " | cut -d$" " -f10 | tail -n +8 | head -n -1 | paste -sd+ | bc`/ `nproc` | python

ソース(記述): https://mohammadg.com/programming/how-to-get-overall-cpu-utilization-from-the-bash-command-line/

1
Mo Beigi

次のようにして、各コアの周波数を確認できます。

$ cat /proc/cpuinfo
0
joe