Linux 講座 / プロセスの確認・一時停止・終了
Linuxでプロセスを管理する際には、実行中の対象を確認し、状態とリソース使用量を見た後、必要な場合にのみシグナルを送って停止または終了させます。psは時点ごとのリストを、topは更新される画面を表示します。終了する際にはまず正常終了を要求するTERMを使用し、強制終了のKILLは最後の手段として残してください。
この記事はプロセス状態・作業制御・シグナルの基礎実習です。親が終了した後の再親化・ゾンビ・PID名前空間についてはPID・PPID補足説明で読むことができます。
プロセスとシェルのジョブを区別する
プロセスは実行中のプログラムのインスタンスであり、PID(プロセスID)で識別されます。PPID(親プロセスID)は現在の親プロセスを指します。親の終了などで別のプロセスに引き継がれると、作成時の親と異なる場合があります。1つのシェルで開始したジョブ(job)はシェルが管理する実行単位であり、1つのジョブに複数のプロセスが含まれることもあります。%1のようなジョブ番号はそのシェルのジョブ制御で使われ、システム全体で使われるPIDと同じではありません。
サービスが実行しているプロセスもありますが、すべてのプロセスがサービスというわけではありません。サービスマネージャーが管理するサービスを再起動するには、プロセスを勝手に1つ終了させる前にサービスマネージャーの状態やログを確認する必要があります。この講座は一般ユーザーが自分の実習用プロセスを確認・制御することに重点を置きます。
psで必要な列だけを選んで確認する
psはコマンドを実行した瞬間のプロセス一覧を出力します。システム全体を見る場合は、必要な列を指定すればPID・親・ユーザー・状態・実行時間・コマンドを一目で比較できます。出力が長くなることがあるので、必要な対象があればPIDやコマンド名で範囲を絞ってください。
ps -eo pid,ppid,user,stat,etime,args
ps -eo pid,ppid,user,%cpu,%mem,stat,args --sort=-%cpu | head
2つ目の例は%CPUを基準に降順で並べた前半部分です。CPU数値は測定・表示方法の影響を受けるため、瞬間的な画面だけで障害の原因を断定しないでください。STATの最初の文字は代表的な状態を示します。Rは実行中または実行待ち、Sは割り込み可能な待ち、Dは通常、割り込み不可能な待ち、Tは停止、Zは子が終了したが親がまだ回収していないゾンビ状態です。後ろに付く文字は追加の特性を意味することがあります。
topとpgrepで変化を見る
topはプロセスの一覧とリソース使用状況を定期的に更新します。画面の並べ替え基準や表示値は環境によって異なり、終了するにはqを押します。繰り返しpsを実行する代わりに、変化の流れを見たいときに便利です。
top
コマンド名でPIDを探す場合はpgrepを使用できます。-aはPIDとコマンドラインを一緒に表示します。名前が似ているプロセスが複数存在することがあり、対象は検索直後に終了したり、PIDが再利用されることがあるので、見つけた番号だけを信じてすぐに終了しないでください。
pgrep -a sleep
検索結果がない場合は、その名前のプロセスが存在しないか、現在のユーザーに情報の制限があるか、検索条件が合っていない可能性があります。自分のプロセスを指定して観察する場合は、次の実習のようにシェルが記録したPIDを使うほうが明確です。
自分のプロセスを一時停止して再実行する
次の例はBashで実行します。sleep 300 &は300秒間待機するプロセスをバックグラウンドで開始し、$!はちょうど開始したバックグラウンドジョブのPIDです。他のユーザーのプロセスや稼働中のサービスを対象にこのシグナル実習を行わないでください。例が終わる前にシェルを閉じると実習のPIDを失う可能性があるため、同じシェルで最後まで進めます。
sleep 300 &
practice_pid=$!
printf 'practice PID: %s\n' "$practice_pid"
ps -p "$practice_pid" -o pid,ppid,stat,etime,args
kill -STOP "$practice_pid"
ps -p "$practice_pid" -o pid,stat,args
kill -CONT "$practice_pid"
ps -p "$practice_pid" -o pid,stat,args
最初のpsで該当するsleepが見えれば対象は正しいです。STOPの後には通常状態の最初の文字がTで表示され、CONTの後には再び待機状態Sなどに変わります。実際の状態は観察時点によって異なります。STOPは終了ではなく実行中断であり、CONTは中断されたプロセスの実行を再開します。
TERMで終了を要求し結果を確認する
実習を終えるときは同じシェルで以下のコマンドを実行します。TERMはプロセスに整理作業を行う機会を与える基本の終了シグナルです。waitは子プロセスが終了するまで待ち、終了状態を回収します。シグナルで終了したためwaitの終了状態は0でない場合があります。
kill -TERM "$practice_pid"
wait "$practice_pid"
ps -p "$practice_pid" -o pid,stat,args
最後のpsでヘッダーだけ出るか対象がないという意味で終了すれば、通常そのPIDの実習プロセスは消えたことになります。ただしPIDは再利用される可能性があるため、長い時間後に同じPIDが見えても同一プロセスとは断定しないでください。プログラムがTERMを無視したり整理中であれば、少し待って状態とログを確認します。
kill -KILL PIDはプロセスにシグナルを処理する機会や終了処理の機会を与えません。データを記録中のプログラム、データベース、サービスに使用すると、状態が一貫しない可能性があるため、原因と対象が明確で正常終了が失敗したときのみ検討してください。権限のないプロセスには、一般ユーザーはシグナルを送ることができません。終了しないD状態は、強制シグナルだけでは即座に解消されない場合があります。
シェルのフォアグラウンドとバックグラウンド
Bashではコマンド &はジョブをバックグラウンドで開始し、jobs -lは現在シェルが追跡しているジョブ番号とPIDを表示します。これは他のターミナルやシステム全体のすべてのプロセスリストではありません。フォアグラウンドで実行したジョブをCtrl+Zで停止した場合、bg %1でバックグラウンドで再開するか、fg %1でフォアグラウンドに戻すことができます。実際のジョブ番号はjobsの結果を見て選択する必要があります。
jobs -l
単純にターミナルでバックグラウンドに回しただけでは、ログアウト後も安定して実行されるサービスにはなりません。セッション・入出力・シグナルの影響を受けます。継続的に管理するサーバープロセスは、該当するディストリビューションのサービス管理方式を使用するのが適しています。
プロセスが問題の場合の判断順序
psやpgrepで PID・コマンド・所有ユーザー・親プロセスを確認します。名前だけで対象を推測しません。topに関連するログで CPU・メモリ使用が持続しているか、単なる待機か、エラーがあるかを確認します。- サービスに属するプロセスか確認します。サービスであれば管理ツールとサービスログを先に確認します。
- 自分のプロセスを停止する必要がある場合、
TERMに正常終了を依頼して十分に待ちます。必要な場合のみ追加の措置を選びます。 - 終了後、再び
psで確認し、再起動・再発の有無や原因を調査します。
公式ドキュメント
ps(1) マニュアルは出力フィールドとステータスコードを、pgrep(1) マニュアルは検索条件を、kill(1) マニュアルはシグナル送信を説明します。シェルジョブ番号と fg・bg の違いについては、GNU Bash ジョブ制御ドキュメントを参照してください。




