labunix's blog

labunixのラボUnix

debian Wheezyで目的のPIDを探す方法

■debian WheezyでPIDを探す方法
 PIDの取得は目的があって探すことがほとんど。
 本当にPIDだけを知りたいなら、以下で良い。

$ pgrep bash
9995
10565
10769

■目的を達成できれば方法はどうでもよいのだけど、
 例えば「ps -ef」がSolarisでエラーになって困る前に、
 マニュアルやヘルプを見て、目的の情報を過不足なく取得する方法を
 身につけておくと良いと思う。

■「ps」マニュアルの抜粋

$ man ps | grep "^pid\|^stat \|^comm[a ]\|^\%cpu\|^\%mem\|^Z.*ゾンビ"
Z    終了したが、親プロセスによって回収されなかった、 消滅した (ゾンビ) プロセ
%cpu       %CPU     プロセスの cpu 使用率は "##.#" というフォーマットである。
%mem       %MEM     マシンの物理メモリに対するプロセスの常駐セットサイズのパー
comm       COMMAND  コマンド名 (実行ファイル名のみ)。 引き数を変更したものは表
command    COMMAND  args を参照。(別名 args, cmd)。
pid        PID      プロセスのプロセス ID 番号。
stat       STAT     複数文字のプロセス状態。 それぞれの値の意味は、 「プ

■「ps」のユーザ定義フォーマットのヘッダ。

$ sudo ps axo pid,stat,cmd,%cpu,%mem | head -1
  PID STAT CMD                         %CPU %MEM

■以下はサンプルなので、そうそう70%の閾値を超えたりしないので、
 ここではその閾値をCPUは0.1%、メモリは1%としている。

■閾値を超えたメモリを使用しているPIDを含むリスト

$ sudo ps axo pid,stat,cmd,%cpu,%mem | awk '($(NF)>1){print}'
 2739 Ss   /usr/sbin/amavisd-new (mast  0.0  4.6
 3132 S    /usr/sbin/amavisd-new (ch2-  0.0  4.7
 3133 S    /usr/sbin/amavisd-new (ch2-  0.0  4.7
 3872 Ss   /usr/sbin/spamd --create-pr  0.0  2.9
 3996 S    spamd child                  0.0  2.7
 3998 S    spamd child                  0.0  2.7
 4579 S    (squid) -D -YC               0.3  1.6

■閾値を超えたCPUを使用しているPIDを含むリスト

$ sudo ps axo pid,stat,cmd,%cpu,%mem | awk '($(NF-1)>0.1){print}'
 4579 S    (squid) -D -YC               0.3  1.6
 9894 Ss   -bash                        0.2  0.1

■コマンドオプションをすべて見たいなら順序を変えれば良い。
 スペースを含む可能性があるので、条件式は前から数える必要がある。

$ sudo ps axo pid,stat,%cpu,%mem,cmd | awk '($3>0.1){print}'
 4579 S     0.3  1.6 (squid) -D -YC

$ sudo env COLUMNS=300 ps axo pid,stat,%cpu,%mem,cmd | awk '($4>1){print}'
 2739 Ss    0.0  4.6 /usr/sbin/amavisd-new (master)
 3132 S     0.0  4.7 /usr/sbin/amavisd-new (ch2-avail)
 3133 S     0.0  4.7 /usr/sbin/amavisd-new (ch2-avail)
 3872 Ss    0.0  2.9 /usr/sbin/spamd --create-prefs --max-children 5 --helper-home-dir -d --pidfile=/var/run/spamd.pid
 3996 S     0.0  2.7 spamd child
 3998 S     0.0  2.7 spamd child
 4579 S     0.3  1.6 (squid) -D -YC

■ゾンビプロセスを探す
 セッションの「s」が付いても良いようにZの後ろにスペースは入れない。

$ sudo ps axo pid,stat,ucmd,%cpu,%mem | grep " Z"

■Linux/FreeBSDなら、「D」の割り込み不可能なスリープ状態、
 または、ディスクI/O処理中の状態も探せる。

$ sudo ps axo pid,stat,ucmd,%cpu,%mem | grep " D"

■ところで、ゾンビプロセスのスタータスはtopにもある。

$ man top 2>&1| grep -A 6 "w\: S"
       w: S  --  プロセス状態
          タスクの状態は以下のいずれかである:
             'D' = 割り込み不可能なスリープ状態
             'R' = 実行中
             'S' = スリープ状態
             'T' = トレース中/停止された
             'Z' = ゾンビ

■なので、以下でも探せる。

$ top -b -n 1 | grep ' Z '

■apache2のプロセス一覧

$ sudo ps axo pid,stat,ucmd,%cpu,%mem | grep apache2
 3620 Ss   apache2          0.0  0.2
10241 S    apache2          0.0  0.1
10278 Sl   apache2          0.0  0.2
10282 Sl   apache2          0.0  0.2

■ここまでの条件のPIDはパイプで「awk '{print $1}'」に渡すと
 以下のようにリスト化出来る。

$ sudo ps axo pid,stat,cmd,%cpu,%mem | awk '($(NF)>1){print}' | awk '{print $1}'
2739
3132
3133
3872
3996
3998
4579

■ところで「grep」をgrepすると以下になる。
 これは「apache2」では引っかからない。

$ sudo ps axo pid,stat,ucmd,%cpu,%mem | grep grep
10451 S+   grep             0.0  0.0

■以下は「grep」自身も含まれる。

$ sudo ps aux | grep apache2
root      3620  0.0  0.2  81592  5688 ?        Ss    8月21   0:14 /usr/sbin/apache2 -k start
www-data 10294  0.0  0.1  81104  3180 ?        S    23:19   0:00 /usr/sbin/apache2 -k start
www-data 10296  0.0  0.2 305272  4244 ?        Sl   23:19   0:00 /usr/sbin/apache2 -k start
www-data 10297  0.0  0.2 305344  4236 ?        Sl   23:19   0:00 /usr/sbin/apache2 -k start
labunix  10467  0.0  0.0   7408   832 pts/0    S+   23:23   0:00 grep apache2

■「apache2」なのか「httpd」なのか分からずgrepすれば「grep」自身は除外される。

$ sudo ps aux | grep [ha][tp][ta][pc][dh]
root      3620  0.0  0.2  81592  5688 ?        Ss    8月21   0:14 /usr/sbin/apache2 -k start
www-data 10294  0.0  0.1  81104  3180 ?        S    23:19   0:00 /usr/sbin/apache2 -k start
www-data 10296  0.0  0.2 305272  4244 ?        Sl   23:19   0:00 /usr/sbin/apache2 -k start
www-data 10297  0.0  0.2 305344  4236 ?        Sl   23:19   0:00 /usr/sbin/apache2 -k start

■「[a]pache2」を除外して、「grep」をgrepする。
 「grep [a]pache2」の場合、「apache2」では引っかからないことが分かる。

$ sudo ps aux | grep -v [a]pache2 | grep grep
labunix  10480  0.0  0.0   7408   840 pts/0    S+   23:24   0:00 grep -v [a]pache2
labunix  10481  0.0  0.0   7404   832 pts/0    S+   23:24   0:00 grep grep

■なので、コマンド名で引っ掛ける時はいずれかの文字を「[]」でくくる。

$ sudo ps aux | grep [a]pache2 
root      3620  0.0  0.2  81592  5688 ?        Ss    8月21   0:14 /usr/sbin/apache2 -k start
www-data 10294  0.0  0.1  81104  3180 ?        S    23:19   0:00 /usr/sbin/apache2 -k start
www-data 10296  0.0  0.2 305272  4244 ?        Sl   23:19   0:00 /usr/sbin/apache2 -k start
www-data 10297  0.0  0.2 305344  4236 ?        Sl   23:19   0:00 /usr/sbin/apache2 -k start

$ sudo ps aux | grep apache[2]
root      3620  0.0  0.2  81592  5688 ?        Ss    8月21   0:14 /usr/sbin/apache2 -k start
www-data 10294  0.0  0.1  81104  3180 ?        S    23:19   0:00 /usr/sbin/apache2 -k start
www-data 10296  0.0  0.2 305272  4244 ?        Sl   23:19   0:00 /usr/sbin/apache2 -k start
www-data 10297  0.0  0.2 305344  4236 ?        Sl   23:19   0:00 /usr/sbin/apache2 -k start