psコマンドでCPU使用率を監視する


懲りずにシェルスクリプトです。

会社の古いサーバから出てきたPerlの監視スクリプトをシェルスクリプトにして書きなおしてみました。

#! /bin/bash

LIMIT=70.0

for i in $(ps aux | sed -e 's/  */ /g' -e 's/ /=/g' -e '1d' | cut -d '=' -f 1-3 )
do
    CPU=$(echo $i | cut -d '=' -f 3)
    v=$(echo "${CPU} <= ${LIMIT}" | bc)
    [ $v -eq 1 ] && continue
    USER=$(echo $i | cut -d '=' -f 1)
    PID=$(echo $i | cut -d '=' -f 2)
    echo "CPU => ${CPU} % : USER => ${USER} : PID => ${PID}"
done

最初のリスト作成が随分ごちゃごちゃしましたが、

  1. ps auxを実行
  2. 標準出力をsedが受け取り、まずは1個以上の半角スペースを1個に置換
  3. 半角スペースを「=」に置換
  4. 1行目を削除
  5. さらにcutが標準出力を受け取り、「=」区切りの1~3番目のフィールドの値を取得する

こんな感じですね。

【2】の置換方法は思いつかなかったので検索で発見。勉強になりました。

これにより、

[paz@paz-para::(2139):(68):(2):~ ]$ ps aux | sed -e ’s/ */ /g’ -e ’s/ /=/g’ -e ‘1d’ | cut -d ‘=’ -f 1-3
root=1=0.0
root=2=0.0
root=3=0.0
root=4=0.0



root=24689=0.0
ntp=30319=0.0

こんな感じで「ユーザー名=プロセスID=CPU使用率」を取得できます。
後は、3つめのフィールド(CPU使用率)をbcコマンドに渡して、しきい値と比較し、しきい値を超えていたら出力しています。
実際に利用する時にはメールで通知するようにしようかと思います。

ちなみに、psコマンドで確認できるCPU使用率は、

  • プロセスの生存期間中に実行に利用した時間のパーセンテージで表される

とのこと。
なので、psコマンドで「%CPU」の値が高くても、その瞬間にCPUを占有しているわけではないようです。不要なプロセスが残ってしまっている可能性なんかもあるのでしょうか?
この辺はまた機会があればゆっくりと調べたいです。

で、「サーバ遅くね?」とか言われたときにとりあえず

$ ps aux

もしくは、

$ ps -aux

を実行していたのですが、manページをみてみると、

“ps -aux” は “ps aux” とは異なることに注意すること。 POSIX と UNIX 標準では、”ps -aux” は “x” という名前のユーザーが所有する全てのプロセスを表示し、かつ -a オプションで選択される全てのプロセスを表示する。 “x” という名前のユーザーが存在しない場合、この ps は代わりに “ps aux” というコマンドとして解釈され、警告を表示する。

とのこと。

後者は間違っていたんですね。

  1. 「-a」でセッションリーダ と端末を持たないプロセスを除く、全てのプロセスを表示する
  2. 「-x」で実効ユーザー ID (EUID) または実効ユーザー名で選択する
    ※-auxとした場合はユーザーは「x」となる
  3. でも「x」というユーザーは存在しない
  4. なので、「ps aux」と解釈して処理を実行する

こんな感じでしょうか。
理解度半分です。

また、manページに簡単な使い方も載っていました。

■標準的な書式を使ってシステム上の全てのプロセスを表示する

$ ps -e
$ ps -ef
$ ps -eF
$ ps -ely

■BSD 書式を使ってシステム上の全てのプロセスを表示する

$ ps ax
$ ps axu

■プロセスツリーを表示する

$ ps -ejH
$ ps axjf

■スレッドに関する情報を取得する

$ ps -eLf
$ ps axms

■セキュリティ情報を取得する

$ ps -eo euser,ruser,suser,fuser,f,comm,label
$ ps axZ
$ ps -eM

■root (実 (real) ID と実効 ID) として実行されている全てのプロセスをユーザ形式で表示する

$ ps -U root -u root u

■全てのプロセスをユーザー定義フォーマットで表示する

$ ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
$ ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
$ ps -eopid,tt,user,fname,tmout,f,wchan

■syslogd のプロセス ID のみを表示する

$ ps -C syslogd -o pid=

■PID 42 の名前のみを表示する

$ ps -p 42 -o comm=

とても覚え切れないので都度、manページを参照することにします。
manが日本語だとほんとに助かります。

psコマンドをはじめて調べましたが、やはりプロセス系は苦手意識が強いです。
克服しなきゃなーと反省しました。

, ,

  1. No comments yet.
(will not be published)
  1. No trackbacks yet.