プログラムがバックグラウンドでハングアップし、CPU使用率が高くなることがあります。どのプロセスが現時点で最大のCPU負荷を引き起こしているのかをプログラムで確認して強制終了する方法はありますか?
この種の作業に気づいている場合は、おそらくよりよく機能するUnixコマンドのファミリーがあります。
これらのツールを使用して、特に不正行為のプロセスが名前でわかっている状況で、「攻撃」をより的を絞ったものにすることができます。
Chromeで繰り返し問題が発生し、最終的にはそれをkillして対処する必要があります。通常、このコマンドを実行して、それらすべてを根絶します。
$ killall chrome
しかし、最新のプロセスのみを処理するために、これを行うこともできます。
# to list
$ pgrep -n chrome
23108
# to kill
$ pkill -n chrome
-f
スイッチを追加して、実行可能ファイルの名前だけでなく、一致させたい長いパス引数を持つプロセスに到達することもできます。
たとえば、次のプロセスがあるとします。
$ ps -eaf | grep some
saml 26624 26575 0 22:51 pts/44 00:00:00 some weird command
saml 26673 26624 0 22:51 pts/44 00:00:00 some weird command's friend
saml 26911 26673 8 22:54 pts/44 00:00:00 some weird command's friend
それらはARGVがこれらの名前に設定されたBashシェルです。ちなみに、私はこのトリックを使用してそれらのプロセスを作りました:
$ (exec -a "some weird command name's friend" bash)
しかし、私にはそれらがたくさんあり、コマンドラインに "友達"がいるため、特定のセットだけを追跡したいとします。私はこれを行うことができます:
$ pgrep -f friend
26673
26911
そして、それらがいくつかあり、最新のものに行きたい場合は、-n
スイッチを再びミックスに追加します。
$ pgrep -fn friend
26911
-f
スイッチを登録するときに正規表現を使用することもできるため、次のように機能します。
$ pgrep -f "weird.*friend"
26673
26911
-l
スイッチを使用して、プロセス名を再確認できます。
$ pgrep -f "weird.*friend" -l
26673 some weird command's friend
26911 some weird command's friend
またはpgrep
に、コンマ(,
)を使用して区切られたプロセスIDをリストするように指示します。
$ pgrep -f "weird.*friend" -d,
26673,26911
あなたはこのようなクールなことをすることができます:
$ ps -fp $(pgrep -f weird -d,)
UID PID PPID C STIME TTY TIME CMD
saml 26624 26575 0 22:51 pts/44 00:00:00 some weird command
saml 26673 26624 0 22:51 pts/44 00:00:00 some weird command's friend
saml 26911 26673 0 22:54 pts/44 00:00:00 some weird command's friend
上記を使用して、CPU使用率の高いプロセスを追跡する際の選択性を高めます。あなたはこれらの方法を使用して殺害のアプローチを使用することができます:
# newest guys
$ pkill -nf vlc ; pkill -nf opensnap
# kill all of these
$ killall vlc; killall opensnap
彼らのCPU負荷を見てください:
$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | grep -v grep
26911 0.1 112m 106m 6408 848 4900 1512 0 0 S 20 0 0.0 some weird command's friend
26673 0.1 112m 106m 6392 848 5020 1504 0 0 S 20 0 0.0 some weird command's friend
ここでは、区切り文字をコンマ(,
)から変更しました。このスイッチ-d,
からパイプ(|
)への別名。このスイッチは-d\|
なので、grep
で使用できます。これを行うと、次のようなプロセスIDが返されます。
$ pgrep -f "weird.*friend" -d\|
26673|26911
次に、これらをgrep -E ...
コマンドに挿入して、特定のプロセスIDに基づいてtop
からの出力をフィルター処理できるようにします。
これは多くの逆戻りのように思えるかもしれませんが、使用しているプロセスIDが「weird。* friend」という名前の特定のプロセスに関連するものだけであることが確実にわかりました。
ここから、本当にCPUが最も高いプロセスを見つけて強制終了することができます。
$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | \
grep -v grep | sort -nk14,14 | tail -1
26911 0.1 112m 106m 6408 848 4900 1512 0 0 S 20 0 0.0 some weird command's friend
上記は、CPU列(14番目)によってtop
からソートされた出力を示しています。それは最低から最高にソートされているので、最後の行(tail -1
)を使用します。これは、「weird。* friend」プロセスの最高のCPUプロセスです。
プログラム「および」、Auto-Nice Daemonは、その効果に対して何かを実行するように設定できます。
いくつかの特定の既知のトラブルメーカーと3レベルの再ナイス(次第に厳しく再ナイスできるようにする)を使用してリストを設定しますが、そのいずれかは、通常は次のように予約されていますが、プロセスを強制終了する可能性があります最後の手段。
CPU負荷の特定の望ましいレベルを達成するために物事を規制することは必ずしも容易ではありませんが、cpulimitなどの役立つ可能性のある(そして違反を防ぐことにより、問題のあるプロセスの強制終了を回避するのに役立つ)他のツールがあります。ニースとイオニスのプログラム。
編集済みスクリプト
@ msw、@ sim、および他のユーザーが、私のスクリプトの概念に関して正当な懸念を表明しています。 @simの回答とmswの発言に触発されて、座って特定の問題(時々問題を引き起こす既知のプロセスの組み合わせ)を解決する方法を再考しました。これが私が思いついたものです:
#!/bin/bash
# tries to kill process with highest CPU load
# (if it is part of a specified list of troublemakers)
TROUBLEMAKERS="vlc opensnap glxgears stress"
sleep 1 # wait a few seconds (just as a precaution)
TOPPROCESS=$(top -b -n 1 | sed 1,6d | sed -n 2p)
TOPPID=$(echo "$TOPPROCESS" | awk '{print $1}')
TOPNAME=$(echo "$TOPPROCESS" | awk '{print $12}')
if [[ "$TROUBLEMAKERS" == *"$TOPNAME"* ]]
then
echo "Cause of high CPU load: "$TOPNAME" ("$TOPPID")"
echo "In troublemaker list. Killing..."
kill -9 $TOPPID
else
echo "Cause of high CPU load: "$TOPNAME" ("$TOPPID")"
echo "Not in troublemaker list. Exiting..."
exit 1
fi
exit 0
前のスクリプトとは対照的に、このスクリプトは、CPU負荷が最も高いプロセスを、その名前が既知のトラブルメーカー(システムでロックされる傾向があるプロセス)の数と一致する場合にのみ強制終了します。
元のスクリプト
以下は、システムで瞬間的に最大のCPU負荷を発生させるプロセスを特定して強制終了する簡単なスクリプトです(Xorgは例外で、GUIがクラッシュします)。
#!/bin/bash
# tries to kill process with highest CPU load
# (if it isn't Xorg)
sleep 1 # wait a few seconds (just as a precaution)
TOPPROCESS=$(top -b -n 1 | sed 1,6d | sed -n 2p)
TOPPID=$(echo "$TOPPROCESS" | awk '{print $1}')
TOPNAME=$(echo "$TOPPROCESS" | awk '{print $12}')
if [ "$TOPNAME" != "Xorg" ]
then
kill -9 $TOPPID
else
echo "CPU load caused by Xorg. Exiting."
exit 1
fi
exit 0
TOPPROCESS
スニペットは、commandlinefu.comの this entry に基づいています。
#!/bin/bash
pid=$(ps -eo %cpu,pid --sort -%cpu | head -n 2 | awk '{print $1 " " $2}')
if [[ -n $pid ]]; then
kcpu=$(echo $pid | awk '{print $3}')
kpid=$(echo $pid | awk '{print $4}')
ift=$(echo "90"'<'$kcpu | bc -l)
if [ $ift -eq "0" ]; then
echo "kpid = $kpid"
kill $kpid
fi
else
echo "Does not exist"
fi