Linux プロセスの管理と監視

LinuxBeginner
オンラインで実践に進む

はじめに

この実験(Lab)では、Linux システム上でプロセスを管理および監視するための不可欠なスキルを学びます。フォアグラウンドとバックグラウンドの両方で実行されるプロセスを操作する方法を学ぶことで、コマンドライン環境やシステムリソースをより細かく制御できるようになります。このハンズオン経験は、システム管理者から開発者に至るまで、Linux を扱うすべての人にとって基本となるものです。

まず、& 演算子を使用してバックグラウンドジョブを開始し、jobs でそのステータスを確認することから始めます。次に、ps で実行中のプロセスを検査し、top でリアルタイムのシステムアクティビティを監視し、fgbgCtrl-Z を使ったジョブ制御を練習します。最後に、プロセス管理のライフサイクル全体を網羅するため、renice を使用してプロセスの優先度を調整する方法と、kill コマンドを使用してプロセスを終了する方法を学びます。

&jobs を使用したバックグラウンドプロセスの開始と確認

このステップでは、バックグラウンドでコマンドを実行する方法と、バックグラウンドジョブのステータスを表示する方法を学びます。Linux シェルでは、通常、コマンドを実行すると、それが完了してプロンプトが戻ってくるまで待機します。これをプロセスの フォアグラウンド(foreground) 実行と呼びます。しかし、長時間のタスクを実行する場合、ターミナルで他のコマンドを引き続き入力できるように、バックグラウンド(background) で実行したい場合があります。

コマンドをバックグラウンドで実行するには、コマンドラインの末尾にアンパサンド(&)を追加するだけです。指定した時間だけ一時停止するシンプルなユーティリティである sleep コマンドで試してみましょう。

次のコマンドを実行して、sleep をバックグラウンドで 300 秒間実行します。これにより、次のステップでそのプロセスを操作できるようになります。

sleep 300 &

Enter キーを押すと、次のような出力が表示され、コマンドプロンプトがすぐに戻ってきて、新しいコマンドを入力できるようになります。

[1] 12345

シェルは sleep 300 コマンドをバックグラウンドジョブとして開始しました。この出力には、2つの重要な情報が含まれています。

  • [1]:これはジョブ ID です。シェルは、各バックグラウンドプロセスに一意のジョブ ID を割り当てます。
  • 12345:これはプロセス ID(PID) です。オペレーティングシステムは、実行中のすべてのプロセスに一意の PID を割り当てます。あなたの環境での PID は、この例とは異なります。

プロセスがバックグラウンドで実行されるようになりましたが、そのステータスを確認するにはどうすればよいでしょうか?現在のシェルセッションのバックグラウンドで実行されているすべてのジョブをリスト表示する jobs コマンドを使用できます。

ターミナルで jobs コマンドを実行します。

jobs

出力には、先ほど開始した sleep コマンドが、そのジョブ ID と現在のステータスとともに表示されます。

[1]+  Running                 sleep 300 &

これで、プロセスをバックグラウンドで正常に開始し、そのステータスを確認する方法を理解できました。これは、Linux システムで長時間実行されるタスクを管理するための基本的なスキルです。次のステップでは、このバックグラウンドジョブとの対話方法について見ていきます。

ps を使用した実行中プロセスの確認

このステップでは、ps コマンドを使用して実行中のプロセスを確認します。前のステップでは、jobs コマンドを使用して現在のシェル内のバックグラウンドプロセスを確認しました。しかし、jobs は現在のセッションに限定されています。ps コマンドを使用すると、実行時点におけるプロセスのより広範なスナップショットを取得できます。

まずはオプションなしで ps を実行してみましょう。このコマンドは、現在のユーザーが所有し、現在のターミナルにアタッチされているプロセスのスナップショットを提供します。

ps

出力は最小限であり、おそらく現在のシェル(zsh)と実行したばかりの ps コマンドのみが表示されます。PID はお使いのシステムによって異なります。

  PID TTY          TIME CMD
23882 pts/0    00:00:00 zsh
23953 pts/0    00:00:00 ps

ターミナル内のプロセスだけでなく、システム上で実行されているすべてのプロセスを表示するには、オプションを指定して ps を使用します。非常に一般的で便利な組み合わせは ps aux です。

  • a:すべてのユーザーのプロセスを表示します。
  • u:ユーザー指向の形式で表示します(ユーザー、CPU 使用率、メモリ使用率などを表示)。
  • x:ターミナルにアタッチされていないプロセスも含めます。

何か特定のものを探している場合、プロセスの長いリストを見るだけではあまり役に立ちません。psgrep コマンドを組み合わせて出力をフィルタリングできます。前のステップで開始した sleep プロセスを見つけてみましょう。

ps aux | grep sleep

このコマンドは ps aux の出力をフィルタリングし、「sleep」という単語を含む行のみを表示します。

labex    23885  0.0  0.0   7264   868 pts/0    S    11:50   0:00 sleep 300
labex    23962  0.0  0.0  10788  2240 pts/0    S+   11:52   0:00 grep --color=auto sleep

出力にはおそらく 2 行が表示されます。1 行目は sleep 300 プロセスです。もう 1 行目は ps がプロセスリストを取得した瞬間に実行されていた grep sleep コマンド自体です。sleep 300 の PID(この例では 23885)が、最初にバックグラウンドでコマンドを実行したときに確認した PID と一致していることに注目してください。

プロセスを表示するためのもう一つの人気のある形式は ps -ef です。

  • -e:システム上のすべてのプロセスを選択します。
  • -f:親プロセス ID(PPID)などの有用な情報を含む「フル」形式のリストを表示します。

grep を使用して sleep プロセスを検索し、もう一度試してみましょう。

ps -ef | grep sleep

出力形式は異なりますが、同様の情報を提供します。このビューは、PID および PPID 列を通じてプロセスの階層を確認するのに特に便利です。

UID        PID  PPID  C STIME TTY          TIME CMD
labex    23885 23882  0 11:50 pts/0    00:00:00 sleep 300
labex    23964 23882  0 11:53 pts/0    00:00:00 grep --color=auto sleep

これで、ps を使用してシステムプロセスのスナップショットを取得する方法を理解できました。grep などのツールと組み合わせることで、特定のプロセスをすばやく見つけて確認することができます。

top を使用したシステムリソースの監視

このステップでは、リアルタイムのシステム監視のための強力なツールである top の使い方を学びます。ps はプロセスの静的なスナップショットを提供しますが、top はシステムアクティビティの動的で継続的に更新されるビューを提供するため、リソースを大量に消費するプロセスが発生したときにそれを特定する上で非常に価値があります。

まず、ターミナルで単に top と入力して Enter キーを押します。

top

ターミナルウィンドウ全体が top のインターフェースに切り替わります。データ数秒ごとに更新され、次のような画面が表示されます。

top - 12:05:15 up 15 min,  1 user,  load average: 0.00, 0.01, 0.00
Tasks: 115 total,   1 running, 114 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   1987.2 total,    985.4 free,    501.8 used,    500.0 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.   1325.4 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
      1 root      20   0  167900  12936   8488 S   0.0   0.6   0:01.15 systemd
      2 root      20   0       0      0      0 S   0.0   0.0   0:00.00 kthreadd
...

top のインターフェースは主に 2 つの部分に分かれています。

  • 上部のサマリーエリアには、稼働時間(uptime)、タスク数、CPU 負荷(%Cpu(s))、メモリ使用量(MiB Mem)などのシステム全体の統計が表示されます。
  • 下部のプロセスリストには、デフォルトで CPU 使用率(%CPU)の降順にソートされた個々のプロセスが表示されます。

top コマンドはインタラクティブです。さまざまなキー操作を使用して動作を変更できます。いくつか試してみましょう。

M(大文字の 'm')を押して、メモリ使用量順にソートします。リストが %MEM 列に基づいて再ソートされ、メモリを最も多く消費しているプロセスが最上部に表示されます。

P(大文字の 'p')を押して、CPU 使用率順にソートします。これにより、デフォルトの %CPU 列によるソートに戻ります。

先ほど開始した sleep プロセスを見つけてみてください。CPU を使用していないため、おそらくリストの下の方にあるはずです。下矢印 キーと 上矢印 キーを使用して、プロセスリストをスクロールできます。

観察が終わったら、いつでも top を終了できます。

q を押すと top のインターフェースが終了し、コマンドプロンプトに戻ります。

これで、top を使用してシステム上のプロセスとリソース使用量をリアルタイムで確認できるようになりました。これは、パフォーマンスの問題をトラブルシューティングするシステム管理者にとって必須のコマンドです。

fgbg、および Ctrl-Z によるジョブ制御の管理

このステップでは、実行中のジョブの状態を管理する方法を学びます。バックグラウンドでジョブを開始する方法はすでに知っていますが、フォアグラウンドで長時間のコマンドを開始した後に、ターミナルを操作できるように戻す必要があることに気づいた場合はどうすればよいでしょうか?ジョブ制御を使用すると、プロセスをフォアグラウンドとバックグラウンドの間で移動させたり、一時停止(停止)および再開させたりすることができます。

先ほど開始した sleep 300 プロセスを操作してみましょう。まず、jobs コマンドでステータスを確認し、まだ実行中であることを確認します。

jobs

sleep ジョブがバックグラウンドで実行されているのが確認できるはずです。

[1]  + running    sleep 300

次に、このジョブをフォアグラウンドに持っていきます。これを行うには、fg(foreground)コマンドに続いて、ジョブ ID に % を付けたものを指定します。ジョブ ID は 1 なので、コマンドは次のようになります。

fg %1

シェルにはコマンド名と追加のジョブ情報が表示され、コマンドプロンプトが消えます。ターミナルは sleep 300 コマンドによって「占有」され、終了するのを待っている状態になります。

[1]  + 394 running    sleep 300

プロセスを終了せずにターミナルを解放するには、プロセスを一時停止(stop) させます。キーボードショートカットの Ctrl-Z を押します(Ctrl キーを押しながら Z キーを押します)。

この操作により、プロセスに特別なシグナル(SIGTSTP)が送信され、実行が一時停止します。プロセスが終了するわけではなく、単にサスペンド(一時停止)されます。これを確認するメッセージが表示され、プロンプトが戻ってきます。

[1]  + 394 suspended  sleep 300

ここで、ジョブのステータスをもう一度確認します。

jobs

出力には、ジョブのステータスが「suspended(一時停止)」として表示されます。

[1]  + suspended  sleep 300

停止したジョブは再開させることができます。fg を使ってフォアグラウンドで再開することも、bg を使ってバックグラウンドで再開することもできます。bg コマンドを使用してバックグラウンドで再開してみましょう。

bg %1

シェルは、ジョブが再びバックグラウンドで実行されていることを確認するメッセージを表示します。

[1]  + 394 continued  sleep 300

jobs を使ってもう一度ステータスを確認し、「Running(実行中)」に戻っていることを確認できます。これで、プロセスをバックグラウンドからフォアグラウンドに移動させ、一時停止し、バックグラウンドで再開させることに成功しました。

renice を使用したプロセスの優先度の調整

このステップでは、実行中のプロセスのスケジューリング優先度に影響を与える方法を学びます。Linux では、プロセスの「nice値(niceness)」によって、他のプロセスと比較してどれだけの CPU 時間を取得できるかが決まります。nice 値の範囲は -20(最高優先度)から +19(最低優先度)までです。デフォルトでは、ほとんどのプロセスは nice 値 0 で開始します。nice 値が高いほど、他のプロセスに対して「親切(nicer)」になり、CPU 時間をより容易に譲るようになります。

これまで作業してきた sleep プロセスの優先度を調整します。これを行うには、まずそのプロセス ID(PID)が必要です。psgrep を使用して再度見つけることができます。

ps aux | grep sleep

sleep 300 に対応する行(grep コマンド自体ではない行)を探し、2 番目の列からその PID をメモします。

labex    23885  0.0  0.0   7264   868 pts/0    S    11:50   0:00 sleep 300
labex    24101  0.0  0.0  10788  2240 pts/0    S+   12:15   0:00 grep --color=auto sleep

この例では、PID は 23885 です。以降のコマンドでは、ご自身の出力に表示された PID を使用してください。

次に、プロセスの現在の nice 値(NI)を確認します。-o オプションを指定した ps コマンドを使用すると、カスタムの出力列を指定できます。

ps -o pid,ni,cmd -p <YOUR_PID>

<YOUR_PID> を実際の sleep プロセスの PID に置き換えてください。例:ps -o pid,ni,cmd -p 23885

    PID  NI CMD
  23885   0 sleep 300

予期された通り、デフォルトの nice 値(NI)は 0 です。

それでは、renice コマンドを使用してこの値を変更しましょう。nice 値を 10 に増やし、プロセスの優先度を下げます。通常のユーザーは、自分のプロセスの nice 値を増やす(優先度を下げる)ことのみが許可されています。

renice -n 10 -p <YOUR_PID>

ここでも、<YOUR_PID> をお使いのプロセスの PID に置き換えてください。コマンドは古い優先度と新しい優先度を表示します。

23885 (process ID) old priority 0, new priority 10

最後に、ps コマンドを再度実行して、変更が適用されたことを確認します。

ps -o pid,ni,cmd -p <YOUR_PID>

出力に新しい nice 値が表示されるはずです。

    PID  NI CMD
  23885  10 sleep 300

これで、実行中のプロセスの優先度を正常に変更できました。これは、長時間実行される重要度の低いバックグラウンドタスクが、より重要なフォアグラウンドの作業を妨げないようにするための便利なテクニックです。

kill を使用したプロセスの終了

このステップでは、プロセスを終了する方法を学びます。プロセスの中には自然に終了するものもありますが、不要になったプロセス、動作がおかしいプロセス、または私たちの sleep コマンドのように一時的な目的で開始されたプロセスを手動で停止する必要が生じることはよくあります。そのための主要なツールが kill コマンドです。

kill コマンドは、指定されたプロセスにシグナルを送信します。デフォルトでは、SIGTERM(終了)シグナルが送信され、プロセスにシャットダウンを丁重に要求します。これにより、プロセスは終了する前にクリーンアップ操作を実行する余裕が与えられます。

プロセスを指定するには、プロセス ID(PID)を使用するか、現在のシェル内のバックグラウンドジョブの場合はジョブ ID を使用できます。ジョブ ID を使用する方が便利な場合がよくあります。

まず、sleep ジョブがまだ実行されていることを確認します。

jobs

sleep プロセスがリストに表示されているはずです。

[1]+  Running                 sleep 300 &

次に、ジョブ ID(%1)を指定して kill コマンドを実行し、プロセスを終了させます。

kill %1

コマンドを実行すると、シェルはジョブが終了したことを示すメッセージをターミナルに出力します。このメッセージは、すぐに表示される場合もあれば、もう一度 Enter キーを押した後に表示される場合もあります。

[1]+  Terminated              sleep 300

プロセスが確実に消滅したことを確認しましょう。jobs コマンドを再度実行します。

jobs

このシェルセッションにはアクティブなジョブがもう存在しないため、コマンドは何も出力しないはずです。ps を使用して二重確認することもできます。

ps aux | grep sleep

表示される可能性があるのは、grep sleep コマンド自体のみです。元の sleep 300 プロセスは実行されていません。

プロセスが応答せず、デフォルトの SIGTERM シグナルに反応しない場合は、より強制的なシグナルである SIGKILL(シグナル番号 9)を送信できます。これにより、クリーンアップの機会を与えずにプロセスが即座に終了します。コマンドは kill -9 %1 となります。これは最後の手段としてのみ使用してください。

おめでとうございます!これで、Linux における基本的なプロセス管理のライフサイクル全体(バックグラウンドでのプロセスの開始、pstop を使用した確認、ジョブ制御による管理、優先度の調整、そして最終的なプロセスの終了)を実践できました。

まとめ

この実験(Lab)では、Linux 環境でプロセスを管理および監視するための基本的なスキルを学びました。まず、& 演算子を使用してバックグラウンドでプロセスを実行し、jobs コマンドでそのステータスを確認しました。次に、プロセス ID(PID)などの詳細を見つけるために ps で実行中のすべてのプロセスを検査する方法や、システムリソースの使用状況とアクティブなプロセスをリアルタイムで監視するために top を使用する方法を探求しました。

さらに、フォアグラウンドプロセスを Ctrl-Z で一時停止し、bg でバックグラウンドに移動させ、fg でフォアグラウンドに戻すというジョブ制御の練習をしました。また、renice を使用してプロセスのスケジューリング優先度を調整する方法や、PID を指定した kill コマンドでプロセスを正常に終了させる方法を学びました。