Linux上では、実行処理されているプログラムがプロセスという形で扱われ、それを見ることで正常に処理が進んでいるかを確認することができます。
Linuxでプロセスを調べる代表的なコマンドとしてpsコマンドがありますが、そのほかの方法でもプロセスを知ることができます。
サーバー管理者からみると、プロセスは名前で判別したほうがもちろんわかりやすいのですが、システム上から見た場合、同名のプロセスもあったりするためかえって判別がつきにくくなります。
プロセスは個別に受け持つ役割があるため、別のプロセスを間違って操作してしまうと、親子関係にあるプロセスなどへ影響が及んでしまいます。
そのため、プロセスにはユニークなプロセスIDが割り振られています。
プロセスをプログラムから操作する場合は、このプロセスIDを用いて操作するのが一般的です。
そのプロセスIDを取得する方法をいくつか紹介します。
もっともポピュラーなpsコマンド
プロセスの状態を調べるための最もよく知られているのはpsコマンドだと思います。
# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 2064 632 ? Ss Feb09 0:02 init [3] root 2 0.0 0.0 0 0 ? S Feb09 0:00 [migration/0] root 3 0.0 0.0 0 0 ? SN Feb09 0:00 [ksoftirqd/0] root 4 0.0 0.0 0 0 ? S Feb09 0:00 [watchdog/0] root 5 0.0 0.0 0 0 ? S Feb09 0:00 [migration/1] root 6 0.0 0.0 0 0 ? SN Feb09 0:00 [ksoftirqd/1] root 7 0.0 0.0 0 0 ? S Feb09 0:00 [watchdog/1]
そのサーバー上で動いている全てのプロセスが一覧表示され、状態やどれくらいの負荷がある(CPUやメモリ利用率)かを表示してくれます。
オプションも多彩にありますので、見たい情報に併せて変えてみたり、特定のプロセスに絞ってみたい場合は、grepと組み合わせてみると良いでしょう。
# ps -ef | grep httpd root 6910 6822 0 16:24 pts/1 00:00:00 grep httpd apache 10270 17700 0 Feb15 ? 00:00:00 /usr/sbin/httpd apache 10271 17700 0 Feb15 ? 00:00:00 /usr/sbin/httpd apache 10272 17700 0 Feb15 ? 00:00:00 /usr/sbin/httpd apache 10273 17700 0 Feb15 ? 00:00:00 /usr/sbin/httpd apache 10274 17700 0 Feb15 ? 00:00:00 /usr/sbin/httpd apache 10277 17700 0 Feb15 ? 00:00:00 /usr/sbin/httpd apache 10279 17700 0 Feb15 ? 00:00:00 /usr/sbin/httpd apache 10281 17700 0 Feb15 ? 00:00:00 /usr/sbin/httpd root 17700 1 0 Feb10 ? 00:00:00 /usr/sbin/httpd
左から2番目がプロセスIDとなり、3番目が親のプロセスIDとなります。
上記の場合は、17700がApacheの親プロセスとなり、それに8つの子プロセスが起動しているのがわかります。
psコマンドをグラフィカルにしたpstreeコマンド
psコマンドはフラットにプロセスを表示するため、多少見づらいところがあります。
pstreeコマンドは、プロセスをツリー上に見やすく表示してくれます。
# pstree -cpn
init(1)┬ migration/0(2)
├ ksoftirqd/0(3)
├ watchdog/0(4)
├ migration/1(5)
(略)
└ httpd(17700) ┬ httpd(10270)
├ httpd(10271)
├ httpd(10272)
├ httpd(10273)
├ httpd(10274)
├ httpd(10277)
├ httpd(10279)
└ httpd(10281)
上記のように、httpdプロセスの親プロセスと子プロセスの関係がわかりやすく表示されます。
また、「-p」オプションを付けることでプロセスIDを表示することもできます。
特定のコマンド名からプロセスIDを表示するpidofコマンド
こちらは純粋にプロセスIDだけを表示してくれるコマンドです。
# pidof /usr/sbin/httpd 17700 10281 10279 10277 10274 10273 10272 10271 10270
上記のようにhttpdコマンドを実行しているプロセスIDを全て表示します。
単なるIDの羅列なため、サーバーを管理する上ではあまり使い道がないのですが、プロセスを操作するプログラムを書いたりする場合は、余計な情報が含まれないため有効だったりします。
パッケージで導入した場合に付属する自動起動スクリプト(/etc/rc.d/init.d/)では、停止時にpidofコマンドを使ってプロセスIDを取得し、TERMシグナルをkillコマンドで送って停止させています。(※1)
例えば、Apacheの自動起動スクリプトを覗いてみると
stop() {
echo -n $"Stopping $prog: "
killproc -d 10 $httpd
RETVAL=$?
echo
[ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}
停止命令(stopオプション)をつけた場合に呼び出される関数ですが、その中でkillprocという関数がさらに呼び出されています。
killproc関数は、このApacheの自動起動スクリプトで読み込まれているfunctionsというファイルの中で定義されています。
さらにkillprocというコマンドを覗いてみると、その中で__pids_pidofという関数が呼び出されており(※1)、その中身は
# Output PIDs of matching processes, found using pidof
__pids_pidof() {
pidof -c -o $$ -o $PPID -o %PPID -x "$1" || \
pidof -c -o $$ -o $PPID -o %PPID -x "${1##*/}"
}
のようにpidofコマンドが呼び出されてプロセスIDを取得しています。
※1 実際にはPIDファイルを優先的に探し、存在する場合はその中に書かれているプロセスIDを利用します。
※2 Linuxのディストリビューションやパッケージのバージョンによって内容が異なってきます。
条件付きでプロセスIDだけを取り出せるpgrepコマンド
出力結果は、pidofコマンドに似ているのですが、取り出す際に条件もつけられるpgrepコマンドというのもあります。
実行方法は、pidofと同様にコマンド名を指定します。
# pgrep -f /usr/sbin/httpd 10270 10271 10272 10273 10274 10277 10279 10281 17700
で、さらにこのApacheのプロセスの中からrootで実行しているプロセス(親プロセス)を取り出してみます。
# pgrep -f /usr/sbin/httpd -u root 17700
逆に、root以外(Apacheのユーザーであるapacheユーザー)で実行されているプロセスを指定してみると
# pgrep -f /usr/sbin/httpd -u apache 10270 10271 10272 10273 10274 10277 10279 10281
親プロセス以外のプロセスIDが表示されましたね。
場合によっては、pidofコマンドよりこちらの方がプロセスIDを取得しやすいかもしれません。
プロセスIDを記したPIDファイル
起動するコマンドの種類によっては、プロセス起動時にプロセスIDをファイルに保存する動きをするものがあります。
# ls /var/run/ NetworkManager auditd.pid console dbus klogd.pid netreport pcscd.pid (略)
中を見てみると、単純に親プロセスのIDだけが記載されています。
# cat /var/run/httpd.pid 17700
先ほどのApacheの停止スクリプトでも、最初にこのプロセスIDファイルが存在するかをチェックし、存在する場合はその中に記載されているプロセスIDを停止させるような動きをしています。
/proc プロセス情報を含んだ特殊なファイルシステム
/procディレクトリ以下にもプロセスに関する情報が保存されています。
# ls /proc/ 1 10277 165 1982 2043 2235 2454 2598 2668 367 6788 9 cmdline fb (略)
番号が書かれたディレクトリがずらずらと表示されます。
この番号はプロセスIDを示していて、これらの中にはそのプロセスIDが処理するのに必要な、さまざまな情報が格納されています。
# ls -o /proc/17700 合計 0 dr-xr-xr-x 2 root 0 2月 17 11:21 attr -r-------- 1 root 0 2月 18 16:32 auxv -r--r--r-- 1 root 0 2月 16 10:24 cmdline -r--r--r-- 1 root 0 2月 18 16:32 cpuset lrwxrwxrwx 1 root 0 2月 18 16:32 cwd -> / -r-------- 1 root 0 2月 18 16:32 environ lrwxrwxrwx 1 root 0 2月 10 11:24 exe -> /usr/sbin/httpd dr-x------ 2 root 0 2月 17 11:21 fd -rw-r--r-- 1 root 0 2月 18 16:32 loginuid -r--r--r-- 1 root 0 2月 18 16:32 maps -rw------- 1 root 0 2月 18 16:32 mem -r--r--r-- 1 root 0 2月 18 16:32 mounts -r-------- 1 root 0 2月 18 16:32 mountstats -rw-r--r-- 1 root 0 2月 18 16:32 oom_adj -r--r--r-- 1 root 0 2月 18 16:32 oom_score lrwxrwxrwx 1 root 0 2月 18 16:32 root -> / -r--r--r-- 1 root 0 2月 18 16:32 schedstat -r-------- 1 root 0 2月 18 16:32 smaps -r--r--r-- 1 root 0 2月 16 10:34 stat -r--r--r-- 1 root 0 2月 18 16:32 statm -r--r--r-- 1 root 0 2月 16 10:24 status dr-xr-xr-x 3 root 0 2月 17 11:21 task -r--r--r-- 1 root 0 2月 18 16:32 wchan
先ほどのPIDファイルは消すことはできますが、こちらは特殊なファイルとなっており消すことはできません。
ですので、確実に起動しているプロセスIDの一覧となります。
PIDファイルは一種のロックファイル(プロセスを2重起動しないように)のような扱いなので、/procディレクトリ以下にそのプロセスIDがあるかを厳密にチェックしたほうが、プロセスの稼動を確実に確認することができます。
- 更新情報
2009.02.18 pgrepコマンドに関する情報を追加しました。
[PR]
[PR]
関連記事
chkconfigに登録されていないデーモンのランレベルをいきなり変えてはいけない
不要なApacheやPHPの拡張モジュールを削除するとどれくらい効果があるか調べてみる
ApacheのプロセスがどのPHPプログラムの処理をしているか調べる方法
NFSマウントした領域内でPHPのsession_startを実行すると異様に重い件
PHPのプログラムをデーモンとして動かしてくれるPEAR::System_Daemon
そのユーザーに成り代わってコマンドを実行できる「runuser」コマンド
inotifyを使ってファイルやディレクトリに起きたイベントを簡単に監視する
簡単にファイル検索をするためのlocateコマンドオリジナル活用法