いますぐ実践! Linux システム管理 / Vol.267 / 読者数:2768名またしても、おひさしぶりです! うすだです!
燃え盛る火は衰えることなく、黄金週間をもんもんと過ごしておりましたが、
みなさまはいかがお過ごしでしたでしょうか。 さて、またしても、まぐまぐさんから、最近出してませんよー的な催促…ではなく、 お気遣いをいただいてしまいました。
発行していない状態が半年を過ぎると、休刊状態になってしまいます。 というわけで、黄金週間を無理やり利用して、発行にこぎつけています。
しかし、前回の発行が大晦日、そして今回が黄金週間ですので、この調子ですと、
次の発行はお盆になってしまうかもしれません。 月2回発行のはずが、季刊誌よりも少ない年3回というのは、 無料とはいえほぼ詐欺に等しいので、そろそろなんとかせねばと思っております。 …と思っているだけで、 特に打開策など考える余裕もなく短絡的に休日を休まず過ごしましたが、 4ヶ月ぶりに、はりきってまいっていきます。 今回のお題 - プロセスを調べる (レベル:初級)Linux には - 別に BSD でも Solaris でも Windows でも OS X でも同様ですが - 様々なプロセスが動いています。 今どきは、なんでもかんでも GUI で操作できてしまうため、 プロセスを意識することはあまりないのかもしれません。ですが、 そんなご時世でもコマンドラインで操作したくなることがあるのではないかと思います。 ですので今回は、プロセスを確認したり調べたりするコマンドを、 さらっと簡単にご紹介したいと思います。
具体的には、「ps」「kill」「pgrep」「pkill」「pstree」です。
さて、コマンドラインで操作するといえば、「ps」コマンドでプロセスIDを調べ、 「kill」コマンドでそれらを死に至らしめる、 という冷徹な使い方が定番なのではないでしょうか。 たとえば、「-C」オプションでコマンド名を指定して ps コマンドを実行すると、 以下のように、そのコマンドのプロセスIDなどを確認できます。
$ ps -C iranai.sh
PID TTY TIME CMD
12457 pts/40 00:00:00 iranai.sh
20021 pts/40 00:00:00 iranai.sh
それらを終了させたいなら、プロセスIDを引数に指定して kill コマンドを実行します。 $ kill 12457 20021 psコマンドの出力はプロセスIDとコマンド名だけでいいよという場合は、 「-o」オプションで指定した項目に限定することもできます。
$ ps -C iranai.sh -o pid,comm
PID COMAND
12457 iranai.sh
20021 iranai.sh
項目名の後に「=」をつけると、ヘッダも出力されなくなります。 $ ps -C iranai.sh -o pid=,comm= 12457 iranai.sh 20021 iranai.sh
ですので、直接 kill コマンドに渡すこともできます。 $ kill $(ps -C iranai.sh -o pid=)
ただ、psコマンドの場合、コマンド名が完全に一致する必要があります。 $ ps -C iranai $
ですが、世の中には、「pgrep」という便利なコマンドがあります。 $ pgrep iranai 12457 20021 コマンド名も出力するには「-l」オプション、 引数も含めて全部出力するには「-a」オプションを指定します。 $ pgrep -l iranai 12457 iranai.sh 20021 iranai.sh $ pgrep -a iranai 12457 /bin/sh ./iranai.sh 20021 /bin/sh ./iranai.sh プロセスIDも何も要らない個数だけでいい、というストイックな貴兄は、 「-c」オプションを指定してください。 $ pgrep -c iranai 2 ちなみに、コマンド名以外も対象にする場合は、「-f」オプションを指定します。 $ ./tekitou.sh iranai & $ pgrep -fa iranai 12457 /bin/sh ./iranai.sh 20021 /bin/sh ./iranai.sh 25287 /bin/sh ./tekitou.sh iranai
そして、それらにシグナルを送るには、「pkill」コマンドが便利です。 $ pkill iranai (コマンド名に iranai を含むプロセスにシグナルを送る) $ pgrep -fa iranai 25287 /bin/sh ./tekitou.sh iranai $ pkill -f iranai (コマンドや引数に iranai を含むプロセスにシグナルを送る) $ pgrep -fa iranai $ killと同様、「-シグナル名」オプションで、別のシグナルを送ることも可能です。 たとえば以下の場合、最終兵器的な SIGKILL シグナルを送ります。 $ pkill -KILL iranai
killと同様、「-9」のように数字で指定も可能です。
あと、関連するプロセスをごっそり確認したいとき、 「pstree」コマンドを使うと便利…かもしれません。 そのまま実行すると、すべての先祖である「init」を起点としたプロセスの親子関係を、 ビジュアルに出力してくれます。
$ pstree
init-+-ModemManager---2*[{ModemManager}]
|-NetworkManager-+-dnsmasq
| `-3*[{NetworkManager}]
|-accounts-daemon---2*[{accounts-daemon}]
|-acpid
|-adb---{adb}
...
プロセスIDやユーザを指定すると、それらを起点とします。
$ pstree $(cat /var/run/apache2/apache2.pid)
apache2-+-PassengerWatchd-+-PassengerHelper---6*[{PassengerHelper}]
| |-PassengerLoggin---2*[{PassengerLoggin}]
| `-3*[{PassengerWatchd}]
`-8*[apache2]
同じ名前のプロセスは集約されて「個数*[コマンド]」と出力されます。
$ pstree -c $(cat /var/run/apache2/apache2.pid)
apache2-+-PassengerWatchd-+-PassengerHelper-+-{PassengerHelper}
| | |-{PassengerHelper}
...
| |-PassengerLoggin-+-{PassengerLoggin}
| | `-{PassengerLoggin}
| |-{PassengerWatchd}
| |-{PassengerWatchd}
...
|-apache2
|-apache2
...
また、「-p」オプションでプロセスID、「-s」オプションで親プロセスも出力します。
$ pstree -p $(cat /var/run/apache2/apache2.pid)
apache2(27401)-+-PassengerWatchd(1471)-+-PassengerHelper(1489)-+
| | +
...
$ pstree -s $(cat /var/run/apache2/apache2.pid)
init---apache2-+-PassengerWatchd-+-PassengerHelper---6*[{Passen+
| |-PassengerLoggin---2*[{Passen+
| `-3*[{PassengerWatchd}]
`-8*[apache2]
pstree では、ウィンドウの横幅に合わせて出力できる分出力しますが、 横幅に関係なく全部出力するには、「-l」オプションを指定します。
$ pstree -lp $(cat /var/run/apache2/apache2.pid)
apache2(27401)-+-PassengerWatchd(1471)-+-PassengerHelper(1489)-+-{PassengerHelper}(1492)
| | |-{PassengerHelper}(1493)
...
おわりに以上、プロセスを確認するコマンドをいくつかご紹介しました。
出力だけのコマンドなら、間違えてもエラーになるだけです。
恐れないでまずは実行してみてください。 もう少し深く知りたいという貴兄は、 「--help」オプションをつけて実行してヘルプメッセージを眺めたり、 オンラインマニュアル(man ps など)を食い入るように見つめてください。 宿題の答え前回の宿題は、 SSHの接続を切られる具体的な原因を、調べてみましょう。 でした。
いろいろあるのかなと思いつつ調べてみますと、接続を切られる原因は、
「NAPT(Network Address Port Translation)」を担うルータが、
その変換をやめてしまうこと、だけのようでした。 NAPTを担うルータは、プライベートな LAN にあるマシンのIPアドレスとポート番号を、 (通常はルータに割り当てられた)グローバルなIPアドレスとポート番号に変換するため、 これらの対応を保持する必要があります。 ですが、すべての対応を永久に残しておくことはできないため、 一定期間やりとりのなかったものは、もう通信しないだろうと見切って、 消し去ります。(もちろん、TCP でセッションをきちんと終了した場合は、 見切る必要なく消し去られます。) たとえば Linux の場合は、600秒…つまり10分間やりとりがないと、 もうええやろと判断して、闇に葬り去ります。 $ sysctl net.netfilter.nf_conntrack_generic_timeout net.netfilter.nf_conntrack_generic_timeout = 600
市販のブロードバンドルータなども、同様の処理を行っているようです。
というわけで、前回、ServerAliveInterval をご紹介しましたが、
これを設定しておくと、指定した秒数の間、
サーバからデータを受信しない状態が続けば、
キープアライブなデータを送信して接続確認をします。 これにより、ルータの情報が消し去られず、通信を維持できます。 なお、TeraTerm や Putty などのSSHクライアントには、上記とは別に、 自前でキープアライブな操作をしてくれるものもあります。 ちなみに、サーバでは、ClientAliveInterval, ClientAliveCountMax を設定すると、 クライアントに対して同じことをします。 今回の宿題今回の宿題は、 CPU使用率やメモリ使用率の多い順にプロセスを出力してみましょう。 です。
宿題もゆるめに…。 あとがき先日、iPhone を落っことしました。 駅のホームで、 ああそうだメールを出さねばと思いポケットから勢いよくiPhoneを取り出したところ、 その勢いで iPhone が我が手から離れ、放物線を宙に描いた後地面に落下しました。 しかしその勢いはとどまることを知らず、滑走を続け、 最終的には線路まで落ちていったのでした。 あっと言う間の出来事でした。 その後すぐに電車が入ってきたため、 電車が行ってから駅員さんに拾っていただいたのですが、 背面のカバーと前面の保護シートのご加護があったにもかかわらず、 ガラスがバリッバリに割れてしまっておりました。 幸い、問題なく動作はしていますので、まあ、これもいいネタになるかもと思い、 そのまま使い続けています。 ですが、ガラス面のひび割れが平坦でないからか、最近、 保護シートとの間に空気が入るようになり、操作がしづらくなってきました。 そして、気泡だらけのため、見た目が非常に醜くなっています。
いま、お金と時間をかけて修理するか、なんとか工夫して使い続けるか、
葛藤しているところです。…いえ、本当のところは、それを考える余裕もなく、
後者の方法があったらいいな…と淡い期待をしているだけです。
次回発行までには、何らかの結論を出したいと思います。
今回も、ここまで読んでいただき、誠にありがとうございました。
「いますぐ実践! Linux システム管理」はこちらです。
その他、作者に関するページは、概ね以下にございます。 |
▼ トップ ▼ プロフィール ▼ リンク
▼ 作ってみました
▼ せんでん
▼ 最近読んだ本
▼ 気に入ってる本 |