Linux の 101 試験対策: プロセスの作成、モニター、およびプロセスへのシグナル送信

現在の進行状況を監視する

Linux® でのプロセス管理について学んでください。この記事では、プロセスをフォアグラウンドとバックグラウンドとの間で切り替える方法、実行中のプロセスを調べる方法、プロセスへシグナルを送信する方法、そしてログアウト後も引き続きプロセスを実行させる方法を説明します。この記事の内容は、Linux のシステム管理者として認定するための LPI 101 試験に備えるためにも、自ら活用するために学ぶ上でも役立ちます。

Ian Shields, Senior Programmer, IBM

Ian ShieldsIan Shields は、developerWorks Linux ゾーンの様々な Linux プロジェクトに関わっています。彼はノースキャロライナ州 Research Triangle Park にある IBM のシニア・プログラマーです。1973年にオーストラリアのキャンベラでシステム・エンジニアとして IBM に入社して以来、カナダのモントリオールやノースキャロライナ州 Research Triangle Park で、コミュニケーション・システムやパーベイシブ・コンピューティングに携わってきました。彼はいくつかの特許を保持しています。Australian National University にて純粋数学および哲学で学位を取得し、また North Carolina State University にてコンピューター・サイエンスで修士号と博士号を取得しています。Ian について詳しく知るには、My developerWorks で彼のプロフィールを見てください。


developerWorks 貢献著者レベル

2010年 2月 02日

この連載について

この連載は Linux システム管理タスクの学習に役立つだけでなく、LPIC-1 (Linux Professional Institute Certification レベル 1) 試験に備えるための教材にもなります。

連載の各記事についての説明とリンクについては、連載のロードマップを参照してください。現在進行中のこのロードマップは、LPIC-1 試験の最新の目標 (2009年4月) を反映しています。完成した記事はその都度ロードマップに追加されていきますが、当面は developerWorks の LPI 認定試験対策チュートリアルで同様の教材の以前のバージョンを調べてください。これらのバージョンは、2009年4月より前の LPIC-1 目標に対応しています。

概要

この記事では、プロセスを管理するための基本的な Linux の手法を説明します。この記事で説明する内容は以下のとおりです。

  • フォアグラウンド・ジョブとバックグラウンド・ジョブを管理する方法
  • ログアウトした後も実行し続けるようにプロセスを開始する方法
  • プロセスをモニターする方法
  • プロセスを選択、ソートして表示する方法
  • プロセスにシグナルを送る方法

この記事は、Linux Professional Institute の Junior Level Administration (LPIC-1) 101 試験の主題 103 の 103.5 の試験対策となります。この目標の重要度は 4 です。

前提条件

この連載の記事を最大限に活用するには、Linux の基礎知識と、記事に記載されたコマンドを演習できる実際の Linux システムが必要です。プログラムのバージョンによって出力のフォーマットに違いが出てくる場合もあるため、コマンドの実行結果は必ずしもここに記載するリストや図とまったく同じであるとは限りません。記載するサンプル・コードの結果は、Ubuntu 9.10 (Karmic Koala) ディストリビューションで実行して得られたものです。


フォアグラウンド・ジョブとバックグラウンド・ジョブの管理

Ian とつながるには

Ian は developerWorks で人気の高いお馴染みの著者の 1 人です。Ian が書いたすべての developerWorks 記事を閲覧してみてください。また、My developerWorks では、Ian のプロフィールを調べることや、彼やその他の著者、そして他の読者とつながることができます。

ちょっと立ち止まって考えてみれば、この連載の今までの記事で説明したターミナル・プログラム以外にも、コンピューター上ではさまざまなプロセスが実行されていることは至って明らかです。実際、グラフィカル・デスクトップを使用しているときには、一度に複数のターミナル・ウィンドウを開いていたり、ファイル・ブラウザーとインターネット・ブラウザー、それにゲームやスプレッドシートの他、複数のアプリケーションを同時に開いていたりします。以前、ターミナル・ウィンドウに入力するコマンドの例を紹介しましたが、これらの例では、コマンドを実行した後、そのコマンドの実行が完了するまでは何もせずに待っているだけでした。今回の記事では、ターミナル・ウィンドウを使って一度に複数の操作を行う方法を学びます。

ターミナル・ウィンドウでコマンドを実行するということは、コマンドをフォアグラウンドで実行するということです。そのようなコマンドのほとんどは短時間で完了しますが、例えばグラフィカル・デスクトップを実行していて、そのデスクトップ上にデジタル時計を表示したいという場合を考えてみてください。ここでは、大抵のグラフィカル・デスクトップにはデジタル時計が備わっているという事実は無視し、単なる一例としてデジタル時計を引用します。

X Window System をインストール済みであれば、xclockxeyes などのユーティリティーがすでに用意されているはずです。これらのユーティリティーをまだインストールしていない場合は、xorg-x11-apps または x11-apps という名前のパッケージのなかにユーティリティーがあります。どちらのパッケージもこの演習に使用できますが、ここでは xclock を使用することにします。man ページで説明しているように、グラフィカル・デスクトップでデジタル時計を起動するには以下のコマンドを実行してください。

xclock -d -update 1

-update 1 の部分は、デジタル時計を毎秒更新するという指定です。このように指定しないと、時計は 1 分に 1 度しか更新されません。このコマンドをターミナル・ウィンドウで実行すると、図 1 のような時計が表示され、ターミナル・ウィンドウにはリスト 1 のような内容が表示されているはずです。xclock もなければ、X Window System もないという読者向けに、端末で簡易版デジタル時計を作成する方法をこの後説明します。該当する読者は、とりあえず以降の説明を読み進めて、後から作成した時計で改めてこれらの演習を試してください。

注: この記事を執筆している時点では、デスクトップ効果が有効になっていると xclock に影響するバグが存在していました。このバグによる最も顕著な影響は、タイトル・バーにフォーカスが置かれてもバーが変化しないことです。お使いの xclock がこの記事に示すように表示されない場合は、デスクトップ効果をしばらく無効に設定しておいてください。

図 1. xclock でのデジタル時計
xclock でのデジタル時計
リスト 1. xclock の起動
ian@attic4:~$ xclock -d -update 1

残念ながら、xclock を起動すると、ターミナル・ウィンドウにプロンプトが表示されなくなります。そこで何とかして、ターミナル・ウィンドウに制御を戻す必要があります。幸い、Bash シェルでは Ctrl-z を中断キーとして使用することができます。このキー・コンビネーションを押すと、ターミナル・ウィンドウにプロンプトが再び表示されるようになります (リスト 2 を参照)。

リスト 2. Ctrl-z による xclock の中断
ian@attic4:~$ xclock -d -update 1  
^Z
[1]+  Stopped                 xclock -d -update 1

時計はデスクトップに表示されたままですが、時計の実行は中断されています。中断するということは、まさにこのことです。実際、別のウィンドウを時計の一部にドラッグしても、時計のその一部は再描画もされません。端末の出力メッセージに、「[1]+    Stopped」と示されていることに注目してください。このメッセージが示す 1 は、ジョブ番号です。したがって、時計を再開するには、fg %1 と入力します。あるいはコマンド名やその一部を使用して、fg %xclock、または fg %?cloと入力することもできます。また、パラメーターを指定しないで fg とだけ入力すると、最後に停止したジョブが再開されます。つまり、この例の場合にはジョブ 1 を再開できるということです。fg とだけ入力して再開されたジョブは再びフォアグラウンドで実行されるため、シェル・プロンプトが使えなくなります。そこで必要になるのは、ジョブをバッググラウンドで実行させることです。ジョブをバッググラウンドで実行させるためには bg コマンドを使いますが、bg コマンドの場合のジョブの指定の仕方、そしてそれによる動作は fg コマンドとまったく同じです。

リスト 3 に、xclock ジョブをフォアグラウンドで再開してからジョブを中断する方法を 2 通りの fg コマンド形式で示します。ジョブをもう 1 度中断してから、このリストの最後のコマンドを実行すると、ジョブをバックグラウンドで再開することができます。その後は、端末で他の作業を行っている間も、時計は実行し続けます。

リスト 3. フォアグラウンドまたはバックグラウンドでの xclock の実行
ian@attic4:~$ fg %1
xclock -d -update 1
^Z
[1]+  Stopped                 xclock -d -update 1
ian@attic4:~$ fg %?clo
xclock -d -update 1
^Z
[1]+  Stopped                 xclock -d -update 1
ian@attic4:~$ bg
[1]+ xclock -d -update 1 &

「&」の使用

上記のリストに示されているように、xclock ジョブをバックグラウンドに移すと、「Stopped」というメッセージは表示されず、アンパサンド (&) が表示されて終わります。実のところ、プロセスをバックグラウンドで実行する際にプロセスを中断する必要はまったくありません。コマンドの後ろにアンパサンドを追加するだけで、シェルはそのコマンド (またはコマンド・リスト) をバックグラウンドで開始します。今度はこの方法を使って、背景色に wheat を指定したアナログ時計を起動します。すると図 2 のような時計が表示され、ターミナル・ウィンドウにはリスト 4 のような出力が表示されているはずです。

図 2. xclock でのアナログ時計
xclock でのアナログ時計
リスト 4. & を使用してアナログ xclock をバックグラウンドで開始する場合
ian@attic4:~$ xclock -bg wheat -update 1&
[2] 4320

この場合のメッセージは、前とは少し異なることに注目してください。メッセージはジョブ番号とプロセス ID (PID) を示しています。PID、そしてプロセスの状態についての詳細は追って説明するとして、ここでは jobs コマンドを使って、どのジョブが実行されているのかを調べてみることにします。このコマンドに -l オプションを追加して PID を表示すると、ジョブ 2 の PID は 4320 であることがわかります (リスト 5 を参照)。また、ジョブ 2 のジョブ番号の隣には、これがカレント・ジョブであることを示す正負号 (+) が付いています。ジョブを指定しないで fg コマンドを実行すると、このジョブ 2 がフォアグラウンドで実行されることになります。

リスト 5. ジョブおよびプロセス情報の表示
ian@attic4:~$ jobs -l
[1]-  3878 Running                 xclock -d -update 1 &
[2]+  4320 Running                 xclock -bg wheat -update 1 &

バックグラウンド・ジョブに関連する他の問題に目を向ける前に、簡易版デジタル時計を作成します。この時計では、sleep コマンドを使用して 2 秒間の遅延を発生させ、date コマンドを使用して現在の日付と時刻を出力します。この 2 つのコマンドを while ループと do/done ブロックによりラップすることで、無限ループを作成し、最後に全体を括弧で囲んでコマンド・リストにした後、リスト全体をバックグラウンドで実行するためにアンパサンドを追加します。ループとスクリプトを使用してこれよりも複雑なコマンドを作成する方法は、連載の今後の記事で詳しく説明する予定です。連載の各記事についての説明とリンクについては、連載のロードマップを参照してください。

リスト 6. 簡易版デジタル時計
ian@attic4:~$ (while sleep 2; do date;done)&
[2] 4856
ian@attic4:~$ Tue Jan 19 09:23:30 EST 2010
Tue Jan 19 09:23:32 EST 2010
Tue Jan 19 09:23:34 EST 2010
fTue Jan 19 09:23:36 EST 2010
Tue Jan 19 09:23:38 EST 2010
gTue Jan 19 09:23:40 EST 2010

( while sleep 2; do
    date;
done )
Tue Jan 19 09:23:42 EST 2010
Tue Jan 19 09:23:44 EST 2010
Tue Jan 19 09:23:46 EST 2010
^C

上記のリストでは、簡易版デジタル時計は PID が 4856 のジョブ 2 として実行されています。2 秒間隔で date コマンドが実行されて、日付と時刻がターミナル・ウィンドウに出力されます。上記で強調表示されているのは、ユーザーによる入力の部分です。入力する速度が遅いと、すべてのコマンドを入力し終わるまでに文字の間に出力行が入り込んでくるかもしれません。上記では実際、コマンド・リストをフォアグラウンドで実行するために入力した「f」と「g」の間が数行離れています。fg コマンドを入力し終わると、bash が現在実行中のコマンド (つまり、コマンド・リスト) をシェルに表示します。そしてコマンドは引き続き、2 秒ごとに時刻を出力し続けます。

ジョブがフォアグラウンドで正常に実行されたら、今度はそのジョブを終了 (kill) することも、別の操作を行うこともできます。ここでは、Ctrl-c を実行して「時計」を終了してみましょう。

なぜこのジョブがジョブ 2 になるのか不思議に思われるかもしれません。アナログ時計を終了した時点で実行中だったジョブは 1 つだけで、そのジョブ番号は 1 でした。したがって、この簡易版デジタル時計には次に使用可能なジョブ番号が割り当てられ、ジョブ 2 となりました。

標準入出力とバックグラウンド・プロセス

前の例での date コマンドによる出力では、入力しようとした fg コマンドにエコー出力された文字が入り込んでいました。このことは、興味深い疑問を提起します。それは、バックグラウンド・プロセスに stdin からの入力が必要な場合にはどうなるのかという疑問です。

プロセスをバックグラウンドで開始した場合、そのプロセスを制御する端末は、制御端末という名前で呼ばれます。他のどこかにリダイレクトされない限り、バッググラウンド・プロセスからの stdout ストリームと stderr ストリームは制御端末に送られます。同様に、バックグラウンド・タスクも制御端末からの入力を想定しますが、制御端末にはユーザーが入力する文字をバックグラウンド・プロセスの stdin に送る手段がありません。このような場合には Bash シェルがプロセスを中断するため、プロセスの実行は停止しています。この停止したプロセスをフォアグラウンドで実行すれば、必要な入力を提供できることになります。リスト 7 に記載する単純な例では、コマンド・リストをバッググラウンドで実行し、少ししてから Enter を押すことで、プロセスが停止したというメッセージが表示されています。次にこのプロセスをフォアグラウンドで実行し、行を入力した後に Ctrl-d を押して入力ファイルの終わりをシグナルで合図しています。するとコマンド・リストの実行が完了し、行を入力して作成したファイルの内容を表示することができます。

リスト 7. stdin からの入力の待機
ian@attic4:~$ (date; cat - > bginput.txt;date)&
[2] 5070
ian@attic4:~$ Tue Jan 19 10:33:13 EST 2010


[2]+  Stopped                 ( date; cat - > bginput.txt; date )
ian@attic4:~$ 
ian@attic4:~$ fg
( date; cat - > bginput.txt; date )
some textmore text
Tue Jan 19 10:33:31 EST 2010
ian@attic4:~$ cat bginput.txt 
some text
more text

ログアウト後のプロセス実行

実際には、バックグラウンド・プロセスの標準入出力ストリームをファイルとの間でリダイレクトする必要が生じてくることもあります。そこで浮かんでくるもう 1 つの疑問が、制御端末が終了した場合やユーザーがログオフした場合、このバックグラウンド・プロセスに何が起こるのかということです。その答えは、使用するシェルによって異なります。シェルが SIGHUP (ハングアップ) シグナルを送信するとしたら、プロセスもおそらく終了します。シグナルについては後で説明しますが、ここではこの問題を回避する別の方法を検討します。

nohup

nohup コマンドを使用して開始されたコマンドは、ハングアップ・シグナルを無視し、stdout および stderr をファイルに追加します。デフォルトのファイルは nohup.out または $HOME/nohup.out です。ファイルが書き込み可能でない場合、コマンドは実行されません。出力を別のファイルに送りたい場合には、記事「Linux の 101 試験対策: ストリーム、パイプ、リダイレクト」で説明している方法で stdout、または stderr をリダイレクトします。

nohup コマンドは、パイプラインやコマンド・リストを実行しません。そのため必要な場合には、パイプラインまたはコマンド・リストをファイルに保存してから、sh (デフォルトのシェル) あるいは bash コマンドを使って実行します。スクリプト・ファイルを実行可能にする方法については連載の別の記事で紹介しますが、ここでは一貫して sh または bash コマンドを使ってスクリプトを実行するという方法を採ります。リスト 8 に、先ほど作成した簡易版デジタル時計に nohup コマンドを適用する方法を示します。言うまでもなく、ファイルに時刻を書き込んでもそれほど役には立ちません。また、ファイルは次第に大きくなっていくため、時計の更新は毎秒ではなく、30 秒ごとに行われるように設定しておきます。

リスト 8. スクリプトでコマンド・リストに nohup を使用する場合
ian@attic4:~$ echo "while sleep 30; do date;done">pmc.sh 
ian@attic4:~$ nohup sh pmc.sh&
[2] 5485
ian@attic4:~$ nohup: ignoring input and appending output to `nohup.out'

ian@attic4:~$ nohup bash pmc.sh&
[3] 5487
ian@attic4:~$ nohup: ignoring input and appending output to `nohup.out'

nohup.out の内容を表示すると、各行の時刻が、その 2 行上の行の約 30 秒後になっていることがわかります。

リスト 9. nohup プロセスによる出力
ian@attic4:~$cat nohup.out
Tue Jan 19 15:01:12 EST 2010
Tue Jan 19 15:01:26 EST 2010
Tue Jan 19 15:01:44 EST 2010
Tue Jan 19 15:01:58 EST 2010
Tue Jan 19 15:02:14 EST 2010
Tue Jan 19 15:02:28 EST 2010
Tue Jan 19 15:02:44 EST 2010
Tue Jan 19 15:02:58 EST 2010

古いバージョンの nohup は制御端末にステータス・メッセージを書き込まなかったため、間違ったことをしたとしても、すぐにはそれに気付きませんでした。stdout と stderr の両方をファイルにリダイレクトすると、過去の振る舞いを確認することができます。一方、shbash と入力するよりも、. を使ってコマンドを読み込むほうが簡単だと結論付けたとします。その場合、前と同じく nohup を使用する一方、stdout および stderr の両方をリダイレクトするとどうなるかをリスト 10 に示します。コマンドを入力すると、PID が 5853 のジョブ 4 が開始されたことを示すメッセージが表示されます。ところが再び Enter を押すと、ジョブ 4 が終了コード 126 で終了したという別のメッセージが表示されます。

リスト 10. nohup での誤り
ian@attic4:~$ nohup . pmc.sh >mynohup.out 2>&1 &
[4] 5853
ian@attic4:~$ 
[4]+  Exit 126                nohup . pmc.sh > mynohup.out 2>&1

リスト 11 に、mynohup.out の内容を記載します。これは当然の結果です。nohup を使用してバックグラウンドでコマンドを実行しているときに、source (.) を指定してファイルからコマンドを読み取り、読み取ったコマンドをカレント・シェルで実行しているからです。このような失敗に関して覚えておくべき重要な点は、シェルがバックグラウンド・ジョブの終了ステータスを表示できるように Enter を押さなければならないこと、そして nohup の出力ファイルで実際に何が上手くいかなかったのかを確認しなければならないことです。

リスト 11. 端末に表示されない nohup からのメッセージ
ian@attic4:~$ cat mynohup.out
nohup: ignoring input
nohup: cannot run command `.': Permission denied

次のセクションでは、プロセスの状態に目を向けます。この記事の演習に従っていて、次のセクションに進む前に休憩しようと思っているとしたら、ちょっと待ってください。現在ファイルシステムでは、2 つのジョブによって今まで以上に大きなファイルが作成されているところです。fg コマンドを使用してジョブをフォアグラウンドで実行するようにし、それから Ctrl-c を押して各ジョブを終了することもできますが、もうしばらく実行させておけば、ジョブのモニターやジョブとの対話を行う別の方法を学べます。


プロセスのモニター

この記事の前のほうで、jobs コマンドについて簡単に紹介し、このコマンドを使用してジョブのプロセス ID (PID) をリストする方法を説明しました。

ps

プロセスの状態に関するさまざまな情報を表示するには、ps コマンドを使用することができます。「ps」は、「process status」の頭字語です。ps コマンドは、引数に PID をいくつでも指定して当該プロセスの状態を表示することも、PID を指定せずにプロセスの状態を表示することもできます。-p オプションを指定して jobs コマンドを実行すると、各ジョブのプロセス・グループ・リーダーの PID だけが出力されます。この出力を、ps コマンドへの引数として使用します (リスト 12 を参照)。

リスト 12. バックグラウンド・プロセスの状態
ian@attic4:~$ jobs -p
3878
5485
5487
ian@attic4:~$ ps $(jobs -p)
  PID TTY      STAT   TIME COMMAND
 3878 pts/1    S      0:06 xclock -d -update 1
 5485 pts/1    S      0:00 sh pmc.sh
 5487 pts/1    S      0:00 bash pmc.sh

オプションを何も指定しないで ps を実行すると、その端末を制御端末とするプロセスの一覧が表示されます (リスト 13 を参照)。この一覧には、コマンド欄に pmc.sh が含まれていないことに注目してください。その理由は、じきに明らかになります。

リスト 13. ps によるプロセスの状態の表示
ian@attic4:~$ ps
  PID TTY          TIME CMD
 2643 pts/1    00:00:00 bash
 3878 pts/1    00:00:06 xclock
 5485 pts/1    00:00:00 sh
 5487 pts/1    00:00:00 bash
 6457 pts/1    00:00:00 sleep
 6467 pts/1    00:00:00 sleep
 6468 pts/1    00:00:00 ps

表示する情報の量を制御するオプションには、-f (full)、-j (jobs)、-l (long) などがあります。PID を指定しない場合には、別の便利なオプション --forest を使うことができます。このオプションを指定するとコマンドがツリー階層で表示され、プロセス間の親子関係が示されます。具体的に言うと、上記の一覧に含まれている sleep コマンドは、現在バックグラウンドで実行させている時計スクリプトの子コマンドです。別の時点でこのコマンドを実行したとすると、代わりに date コマンドがプロセスの状態の一覧に含まれる可能性もありますが、このスクリプトの場合、そうなる可能性はほとんどありません。リスト 14 では、これらのオプションのいくつかを指定しています。

リスト 14. プロセスの状態に関する詳細情報
ian@attic4:~$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
ian       2643  2093  0 Jan18 pts/1    00:00:00 bash
ian       3878  2643  0 09:17 pts/1    00:00:06 xclock -d -update 1
ian       5485  2643  0 15:00 pts/1    00:00:00 sh pmc.sh
ian       5487  2643  0 15:01 pts/1    00:00:00 bash pmc.sh
ian       6635  5485  0 15:41 pts/1    00:00:00 sleep 30
ian       6645  5487  0 15:42 pts/1    00:00:00 sleep 30
ian       6647  2643  0 15:42 pts/1    00:00:00 ps -f
ian@attic4:~$ ps -j --forest
  PID  PGID   SID TTY          TIME CMD
 2643  2643  2643 pts/1    00:00:00 bash
 3878  3878  2643 pts/1    00:00:06  \_ xclock
 5485  5485  2643 pts/1    00:00:00  \_ sh
 6657  5485  2643 pts/1    00:00:00  |   \_ sleep
 5487  5487  2643 pts/1    00:00:00  \_ bash
 6651  5487  2643 pts/1    00:00:00  |   \_ sleep
 6658  6658  2643 pts/1    00:00:00  \_ ps

これで、jobs コマンドと ps コマンドを使用してプロセスをモニターする際の基本的なツールを使えるようになりました。次に、プロセスを選択およびソートして表示する方法について説明しますが、その前にあと 2 つ、別のモニター用コマンドを簡単に紹介しておきます。

free

free コマンドは、システム内の空いているメモリー量と使用中のメモリー量を表示します。デフォルトでの表示はキロバイト単位ですが、表示単位の設定は変更することができます。例えばバイトには -b、キロバイトには -k、メガバイトには -m、ギガバイトには -g を指定します。-t オプションを指定すると合計量の行が表示されます。また -s オプションと値を併せて指定すると、指定した値の間隔で最新の情報が表示されます。この値は秒単位ですが、浮動小数点値にすることもできます。リスト 15 に 2 つの例を記載します。

リスト 15. free コマンドの使用
ian@attic4:~$ free
             total       used       free     shared    buffers     cached
Mem:       4057976    1543164    2514812          0     198592     613488
-/+ buffers/cache:     731084    3326892
Swap:     10241428          0   10241428
ian@attic4:~$ free -mt
             total       used       free     shared    buffers     cached
Mem:          3962       1506       2456          0        193        599
-/+ buffers/cache:        713       3249
Swap:        10001          0      10001
Total:       13964       1506      12457

uptime

uptime コマンドを使用すると、現在の時刻、システムのこれまでの稼働時間、現在ログオンしているユーザーの数、そして過去 1 分、5 分、15 分間のシステムの平均負荷がまとめて 1 行で表示されます。リスト 16 に一例を記載します。

リスト 16. システムの稼働状態に関する情報の表示
ian@attic4:~$ uptime
 17:41:17 up 20:03,  5 users,  load average: 0.00, 0.00, 0.00

表示するプロセスの選択およびソート

ps の使用

これまでの例で説明した ps コマンドによって表示されるのは、このコマンドを実行したターミナル・セッションから開始されたプロセスだけでした (リスト 14 の 2 番目の例にある SID (セッション ID) の列に注目)。制御端末を持つすべてのプロセスを確認するには、-a オプションを指定することができます。また、-x オプションを指定すると制御端末を持たないプロセスが表示され、-e オプションを指定するとすべてのプロセスの情報が表示されます。リスト 17 では、制御端末を持つすべてのプロセスを表示する場合の完全なフォーマットを示しています。

リスト 17. 他のプロセスの表示
ian@attic4:~$ ps -af
UID        PID  PPID  C STIME TTY          TIME CMD
ian       3878  2643  0 09:17 pts/1    00:00:06 xclock -d -update 1
ian       5485  2643  0 15:00 pts/1    00:00:00 sh pmc.sh
ian       5487  2643  0 15:01 pts/1    00:00:00 bash pmc.sh
ian       7192  5485  0 16:00 pts/1    00:00:00 sleep 30
ian       7201  5487  0 16:00 pts/1    00:00:00 sleep 30
ian       7202  2095  0 16:00 pts/0    00:00:00 ps -af

TTY 列に表示されている制御端末に注目してください。上記の ps -af コマンドを実行するときに、最初に開いたターミナル・ウィンドウ (pts/0) に切り替えたため、このコマンドは pts/0 で実行されていますが、これまでこの記事のために作成したコマンドは pts/1 で実行されています。

ps には他にも多くのオプションがあります。そのうちのいくつかは、表示するフィールドやフィールドの表示方法を詳細に制御することができます。また、表示するプロセスを制御するためのオプションもあります。例えば、特定のユーザー (-u) や特定のコマンド (-C) に関連するプロセスを選択して表示することができます。リスト 18 には、getty コマンドを実行しているすべてのプロセスが表示されています。ここでは、-o オプションを使用して表示する列を指定しています。さらに、通常表示される内容 (オプションを指定しないで ps を実行した場合に表示される内容) に user オプションを追加したため、どのユーザーが getty を実行しているかも確認することができます。

リスト 18. getty コマンドを実行しているユーザーの確認
ian@attic4:~$ ps -C getty -o user,pid,tty,time,comm
USER       PID TT           TIME COMMAND
root      1192 tty4     00:00:00 getty
root      1196 tty5     00:00:00 getty
root      1209 tty2     00:00:00 getty
root      1219 tty3     00:00:00 getty
root      1229 tty6     00:00:00 getty
root      1731 tty1     00:00:00 getty

出力を特定のフィールドでソートしたいという場合はよくあります。そのような場合には --sort オプションを使ってソート・フィールドを指定することで、その目的を果たせます。デフォルトでは昇順 (+) でソートされますが、降順 (-) を指定することも可能です。リスト 19 に、ps コマンドの最後の例を記載します。この例では、jobs 形式を使ってすべてのプロセスが表示され、出力をセッション ID とコマンド名でソートしています。最初はデフォルトのソート順を使用し、次にセッション ID とコマンド名のソート順を明示的に指定しています。

リスト 19. ps による出力のソート
ian@attic4:~$ ps -aj --sort -sid,+comm
  PID  PGID   SID TTY          TIME CMD
 5487  5487  2643 pts/1    00:00:00 bash
 9434  9434  2643 pts/1    00:00:00 ps
 5485  5485  2643 pts/1    00:00:00 sh
 9430  5485  2643 pts/1    00:00:00 sleep
 9433  5487  2643 pts/1    00:00:00 sleep
 3878  3878  2643 pts/1    00:00:10 xclock
 8019  8019  2095 pts/0    00:00:00 man
 8033  8019  2095 pts/0    00:00:00 pager
ian@attic4:~$ ps -aj --sort sid,comm
  PID  PGID   SID TTY          TIME CMD
 8019  8019  2095 pts/0    00:00:00 man
 8033  8019  2095 pts/0    00:00:00 pager
 5487  5487  2643 pts/1    00:00:00 bash
 9435  9435  2643 pts/1    00:00:00 ps
 5485  5485  2643 pts/1    00:00:00 sh
 9430  5485  2643 pts/1    00:00:00 sleep
 9433  5487  2643 pts/1    00:00:00 sleep
 3878  3878  2643 pts/1    00:00:10 xclock

いつも通り、ps で使用できる多数のオプションとフィールドの詳細については、ps に関する man ページを参照してください。または、ps --help を実行して概要を表示することもできます。

top の使用

プロセスの状態の変化を確認するために ps コマンドを続けて何度も実行しているとしたら、代わりに top コマンドを実行する必要があるかもしれません。このコマンドは、継続的に更新されるプロセスの一覧を便利な要約情報と併せて表示します。リスト 20 に、top によって表示される最初の数行を記載します。top を終了するにはサブコマンド q を使用してください。

リスト 20. top によるプロセスの表示
top - 16:07:22 up 18:29,  5 users,  load average: 0.03, 0.02, 0.00
Tasks: 170 total,   1 running, 169 sleeping,   0 stopped,   0 zombie
Cpu(s):  2.1%us,  0.5%sy,  0.0%ni, 97.4%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   4057976k total,  1543616k used,  2514360k free,   194648k buffers
Swap: 10241428k total,        0k used, 10241428k free,   613000k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 6820 ian       20   0  506m  78m  26m S    1  2.0   0:23.97 firefox
 1381 root      20   0  634m  40m  18m S    1  1.0   2:06.74 Xorg
 2093 ian       20   0  212m  15m  10m S    1  0.4   0:13.53 gnome-terminal
 6925 ian       20   0 1118m 298m  19m S    1  7.5   1:07.04 java
 6855 ian       20   0 73416  11m 8808 S    1  0.3   0:05.01 npviewer.bin
 7351 ian       20   0 19132 1364  980 R    0  0.0   0:00.07 top
    1 root      20   0 19584 1888 1196 S    0  0.0   0:00.74 init
    2 root      15  -5     0    0    0 S    0  0.0   0:00.01 kthreadd

top コマンドには多くのサブコマンドがあります。そのうち、特に便利なサブコマンドを以下に記載します。

h
ヘルプを表示
q
top コマンドを終了
f
表示にフィールドを追加、または表示からフィールドを削除
o
表示の順序を指定
F
ソートの基準とするフィールドを選択

top コマンドのオプションの詳細については man ページを参照してください。man ページには、メモリー使用量や他の基準によって表示をソートする方法も記載されています。リスト 21 は、仮想メモリー使用量を基準に降順でソートした出力の例です。

リスト 21. top による出力のソート
top - 16:21:48 up 18:43,  5 users,  load average: 0.16, 0.06, 0.01
Tasks: 170 total,   3 running, 167 sleeping,   0 stopped,   0 zombie
Cpu(s):  2.1%us,  0.8%sy,  0.0%ni, 96.6%id,  0.0%wa,  0.0%hi,  0.5%si,  0.0%st
Mem:   4057976k total,  1588940k used,  2469036k free,   195412k buffers
Swap: 10241428k total,        0k used, 10241428k free,   613056k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
 6925 ian       20   0 1171m 338m  21m S    0  8.5   1:44.10 java               
 1381 root      20   0  634m  40m  18m S    0  1.0   2:13.63 Xorg                
 6820 ian       20   0  506m  83m  26m S    3  2.1   0:51.28 firefox            
 2004 ian       20   0  436m  23m  15m S    0  0.6   0:01.55 nautilus           
 2031 ian       20   0  419m  13m  10m S    0  0.3   0:00.11 evolution-alarm    
 2118 ian       20   0  372m  10m 7856 S    0  0.3   0:00.06 evolution-data-    
 2122 ian       20   0  344m  13m  10m S    0  0.3   0:00.10 evolution-excha    
 2001 ian       20   0  331m  22m  14m S    0  0.6   0:13.61 gnome-panel        
 1971 ian       20   0  299m 9.9m 7244 S    0  0.3   0:05.00 gnome-settings-    
 1989 ian       20   0  288m  15m  11m S    0  0.4   0:11.95 metacity           
 1954 ian       20   0  265m 5460 3412 S    0  0.1   0:00.28 pulseaudio

プロセスへのシグナルの送信

今度は、プロセスと非同期で通信する手段となる Linux のシグナルに目を向けてみましょう。これまでに SIGHUP シグナルについて触れ、また、Ctrl-c と Ctrl-z の両方を使ってプロセスにシグナルを送信しました。この方法もシグナルを送信する 1 つの方法ですが、一般的には kill コマンドを使用してシグナルを送信します。

kill によるシグナルの送信

kill コマンドは、指定のジョブまたはプロセスにシグナルを送ります。リスト 22 に、SIGTSTP シグナルと SIGCONT シグナルを指定してバックグラウンド・ジョブを停止し、それから再開する方法を示します。SIGTSTP シグナルを指定するということは、fg コマンドによってジョブをバックグラウンドで実行してから、Ctrl-z を使って中断することと同じです。もう一方の SIGCONT シグナルには、bg コマンドを使用した場合と同じような効果があります。

リスト 22. バックグラウンド・ジョブの停止と再開
ian@attic4:~$ kill -s SIGTSTP %1

[1]+  Stopped                 xclock -d -update 1
ian@attic4:~$ jobs -l
[1]+  3878 Stopped                 xclock -d -update 1
[2]   5485 Running                 nohup sh pmc.sh &
[3]-  5487 Running                 nohup bash pmc.sh &
ian@attic4:~$ kill -s SIGCONT 3878
ian@attic4:~$ jobs -l
[1]   3878 Running                 xclock -d -update 1 &
[2]-  5485 Running                 nohup sh pmc.sh &
[3]+  5487 Running                 nohup bash pmc.sh &

この例では、ジョブ (%1) を指定して xclock プロセスを停止し、それからプロセス ID (PID) を指定して、このプロセスを再開 (続行) しています。ジョブ %2 を停止してから -f オプションを指定して tail コマンドを実行すると、1 つのプロセスだけが nohup.out ファイルを更新していることを確認できます。

指定可能なシグナルは他にもたくさんあります。kill -l を実行すると、指定可能なシグナルをシステム上に表示することができます。そのうちの一部は、不正なオペレーション・コードや、浮動小数点例外、プロセスがアクセスできないメモリーへのアクセス試行などといったエラーをレポートするために使用するシグナルです。シグナルには番号 (20 など) と名前 (SIGTSTP など) の両方が付けられていることに注意してください。このため、番号の前に - を付けて指定することも、-s オプションとシグナル名の組み合わせで指定することもできます。例えば私のシステムでは、kill -s SIGTSTP の代わりに kill -20 を使用することができます。この番号はこのシグナルのものであると思い込む前に、必ずお使いのシステムでシグナルの番号を調べてください。

シグナル・ハンドラーとプロセスの終了

Ctrl-c を押すとプロセスが終了することはすでに説明しましたが、これは実際には、SIGINT (中断) シグナルをプロセスに送信するということです。一方、シグナル名を指定せずに kill を実行すると、SIGTERM シグナルが送信されます。プロセスを終了するには大抵、この 2 つのシグナルのどちらを使用しても同じことです。

前に説明したとおり、nohup コマンドにより実行されたプロセスは SIGHUP シグナルを無視します。通常、プロセスはシグナルをキャッチするためのシグナル・ハンドラーを実装することができます。したがって、プロセスが SIGINT または SIGTERM のいずれかをキャッチするシグナル・ハンドラーを実装することも考えられます。シグナル・ハンドラーはどのシグナルが送信されたかを認識するため、例えば SIGINT は無視し、SIGTERM を受信した場合にのみプロセスを終了させるといったことも可能です。リスト 23 に、SIGTERM シグナルをジョブ %2 に送信する方法を示します。プロセスの状態には、シグナルの送信直後に「Terminated」と表示されることに注目してください。代わりに SIGINT を使用したとしたら、「Interrupt」と表示されます。その後すぐにプロセスのクリーンアップが行われ、ジョブがジョブ・リストに表示されなくなります。

リスト 23. SIGTERM によるプロセスの終了
ian@attic4:~$ kill -s SIGTERM %2
ian@attic4:~$ 
[2]-  Terminated              nohup sh pmc.sh
ian@attic4:~$ jobs -l
[1]-  3878 Running                 xclock -d -update 1 &
[3]+  5487 Running                 nohup bash pmc.sh &

シグナル・ハンドラーを使用することで、プロセスは非常に柔軟な動作が可能になります。例えば、プロセスにその通常の操作を実行させながらも、特別な場合にシグナルによってプロセスの実行を中断することができます。プロセスが終了リクエストをキャッチして、ファイルを閉じる、進行中のトランザクションにチェックポイントを付けるなどのアクションを実行できるようにシグナルを使うだけでなく、デーモン・プロセスに構成ファイルを再読み込みさせたり、操作を再開させたりするためにシグナルを使用することも珍しくありません。この手法は、ネットワーク・パラメーターを変更する際の inetd プロセス、または新しいプリンターを追加する際のライン・プリンター・デーモン (lpd) に使用することもできます。

プロセスの強制終了

シグナルのなかには、例えばハードウェア例外などのキャッチできないシグナルもあります。最も使用する可能性の高い SIGKILL は、シグナル・ハンドラーがキャッチできないため、プロセスを強制終了します。一般的に言って、このシグナルが必要になるのは、他のすべての手段でプロセスを終了できなかった場合のみです。


ログアウトと nohup

nohup を使用すると、ログアウトした後もプロセスの実行を続けられることを思い出してください。このコマンドを使用してプロセスがログアウト後も引き続き実行されるようにした上で、再びログインしてみてください。ログインした後、前に行ったように jobsps を使って簡易版デジタル時計の残りのプロセスを確認すると、出力はリスト 24 のようになっているはずです。

リスト 24. 再びログインした後の出力
ian@attic4:~$ jobs -l
ian@attic4:~$ ps -a
  PID TTY          TIME CMD
10995 pts/0    00:00:00 ps

今度は pts/0 で実行していますが、出力には jobs が実行された形跡はまるでなく、ps コマンドの実行結果しか表示されていません。これは、期待していた出力とは違うはずです。ただし、すべてがすべて失われたというわけではありません。仮に、bash で開始した nohup ジョブや、bash で開始した他のジョブを終了したかどうかを思い出せないとします。その場合、前に説明した getty コマンドを実行しているプロセスを調べる方法と同じ方法で、SID、PID、PPID、そしてコマンド・ストリングだけを表示することができます。その上で -js オプションを指定すれば、セッション内のすべてのプロセスを表示できるというわけです。リスト 25 に、この方法による結果を記載します。これ以外にも、ユーザー名で検索してから grep を使用して結果をフィルタリングするなど、これらのプロセスを調べる方法を考えてみてください。

リスト 25. 結果が表示されないコマンドの発見
ian@attic4:~$ ps -C bash -C sh -o pid,sid,tname,cmd
  PID   SID TTY      CMD
 5487  2643 ?        bash pmc.sh
 7050  7050 pts/3    -bash
10851 10851 pts/0    bash
ian@attic4:~$ ps -js 2643
  PID  PGID   SID TTY          TIME CMD
 5487  5487  2643 ?        00:00:00 bash
11197  5487  2643 ?        00:00:00 sleep

pmc.sh は引き続き実行されていますが、制御端末の TTY に関しては疑問符 (?) が示されていることに注意してください。

プロセスの終了方法についてこれまでに得た知識を活用すれば、簡易版デジタル時計の残りのプロセスも、そのプロセスの PID と kill コマンドを使用して終了できるはずです。

参考文献

学ぶために

製品や技術を入手するために

  • developerWorks から直接ダウンロードできる IBM ソフトウェアの試用版を使用して、Linux で次の開発プロジェクトを構築してください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=470143
ArticleTitle=Linux の 101 試験対策: プロセスの作成、モニター、およびプロセスへのシグナル送信
publish-date=02022010