これは、古いバージョンのtopのように見えるものに基づいた非常に壊れやすいスクリプトです。ただし、このスクリプトを調べるのは非常に簡単です。以下から始めます。
top -b -n1
これ ( topのマニュアルを読む)は、 topをバッチ モードにし (つまり、topと対話的にプレイする代わりに、出力を別のコマンドに送りたい)、1 回の反復で出力します。これにより、次のような出力が得られます。
$ top -b -n1
top - 10:48:33 up 1 day, 22:51, 3 users, load average: 1.21, 1.27, 1.03
Tasks: 262 total, 2 running, 260 sleeping, 0 stopped, 0 zombie
%Cpu(s): 14.5 us, 5.2 sy, 11.3 ni, 67.3 id, 1.6 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem: 8124692 total, 6722112 used, 1402580 free, 384188 buffers
KiB Swap: 4143100 total, 430656 used, 3712444 free. 2909664 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
11012 user1 20 0 426412 14436 5740 R 97.1 0.2 19:27.98 dleyna-renderer
4579 root 20 0 286480 152924 31152 S 13.0 1.9 24:15.49 Xorg
1 root 20 0 185288 4892 3352 S 0.0 0.1 0:02.52 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:02.77 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
7 root 20 0 0 0 0 S 0.0 0.0 1:32.00 rcu_sched
これをgrep ^Cpuにパイプすると、この回答で使用しているtopのバージョンが、元のスクリプトが期待していたバージョンと出力が異なる可能性があることを示す破損が発見されたようです。代わりに^%Cpuで一致させることを意図しているようです。これが修正された部分です:
$ top -b -n1 | grep ^%Cpu
%Cpu(s): 14.6 us, 5.2 sy, 11.2 ni, 67.3 id, 1.6 wa, 0.0 hi, 0.1 si, 0.0 st
パイプの次の部分は、 '%Cpu(s): '部分を取り除くことです:
$ top -b -n1 | grep ^%Cpu | awk -F': ' '{print $2}'
15.1 us, 5.0 sy, 10.8 ni, 67.4 id, 1.6 wa, 0.0 hi, 0.1 si, 0.0 st
そして、次の部分... awk -F% '{print $1}' -- スクリプトは%記号の左側にあるものを出力しようとしているため、この回答のバージョンのtopでは意味がありません--出力に%はありません。だから... ここからどこへ行く必要があるのか 疑問に思っています。
スクリプトの残りの部分から...パイプラインの結果は100と比較されます...したがって、スクリプトが解析することを意図したtopのバージョンは、最初の列にCPU使用率の合計のパーセンテージがあったと思います...私たちのトップ出力のバージョンでは、すべてがより細かく分割されています。直前の出力の内訳は次のとおりです。
15.1% -- spent in normal priority user/applications
5.0% -- spent in system/kernel
10.8% -- spent in low priority batch or daemon jobs
67.4% -- spent "idle"
1.6% -- spent waiting for I/O to complete
0.0% -- spent in servicing HW interrupts
0.1% -- spent in servicing software interrupts
0.0% -- spent stolen by another VM running on the HW
------------------------------------------------------
100.0% -- Total
... したがって、最新の Linux システムでは、topはより多くの情報を提供するため、問題を別の方法で見る必要があるかもしれません。この場合、メトリックとして (idle * 10) を見ることができます。シェルと同様に、整数の計算と比較しか使用できません。そのため、スクリプトを少し調整します...そして、その間に、パイプライン内のgrepを取り除きましょう。これは、 awkでも簡単に実行できます。
$ top -b -n1 | awk -F, '/^%Cpu/ {print $4}'
67.8 id
それでは、アイドル値を 10 倍した値になるように調整しましょう。
$ top -b -n1 | awk -F, '/^%Cpu/ { sub(/id/,"",$4); print $4*10 }'
678
元のスクリプトの次の部分では、bcを使用して、100% 使用されているかどうかを確認します。現在、使用率ではなくアイドル状態に注目しているため、元のスクリプトとは反対のものが必要です。また、出力が整数にスケーリングされるようになったので、bcの複雑さは必要ありません。比較にシェルを使用しましょう。
$ if [ $(top -b -n1 | awk -F, '/^%Cpu/ { sub(/id/,"",$4); print $4*10 }') -le 0 ]; then echo '...'; fi
それだけです。
この回答はすべて、コードがどのように機能するかを示すためのものでした-パイプラインを介してtopの出力を解釈および解析する方法、スクリプトの一部が何をするかを理解するタスクを実行する方法、および壊れやすい/を修復する方法壊れたスクリプト。ただし、元のスクリプトは壊れやすいだけでなく、設計上かなり壊れています。過負荷のシステムを検出するために使用するメトリックは、topコマンドの出力の最初の行にある「負荷平均」に似ていますが、 uptimeコマンドの出力から解析できるよりも優れています。
過負荷を調べる方法は、負荷平均を CPU の数で割った値を調べることです。/proc/cpuinfo を解析すると、CPU の数を簡単に確認できます。
$ grep ^processor /proc/cpuinfo | wc -l
4
15 分間で 400% の負荷が継続的な負荷のしきい値と見なされる例を次に示します。
load=$(uptime | awk -F, '{ print $(NF) * 1.0 }')
proc=$(grep ^processor /proc/cpuinfo | wc -l)
plod=$(awk "BEGIN { x = 100 * $load / $proc; print int(x) + int(x+x)%2 }")
if [ $plod -gt 400 ]; then echo '...'; fi
注: int(x) + int(x+x)%2は丸め関数です
システムの空きメモリの量については、schteverの回答が気に入っています。ただし、列 3 ではなく列 4 を使用し、メモリが不足していないかどうかを確認します。