Linux で Bash シェルを使用して、フォアグラウンド プロセスとバックグラウンド プロセスを管理します。 Bash のジョブ制御関数とシグナルを使用すると、コマンドの実行方法をより柔軟に行うことができます。その方法をご紹介します。
プロセスについてのすべて
Linux または Unix 系オペレーティング システムでプログラムが実行されるたびに、プロセスが開始されます。 「プロセス」は、コンピュータのメモリ内で実行中のプログラムの内部表現の名前です。アクティブなプログラムごとにプロセスがあります。実際、コンピュータ上で実行されているほぼすべてのものにプロセスが存在します。これには、 GNOME や KDE などの グラフィカル デスクトップ環境 (GDE) のコンポーネントと、起動時に起動されるシステム デーモンが 含まれます。
なぜほとんどすべてが実行されているのでしょうか? cd 、 pwd 、および alias などの Bash ビルトインは、実行時にプロセスを起動 (または「生成」) する必要はありません。 Bash は、ターミナル ウィンドウで実行されている Bash シェルのインスタンス内でこれらのコマンドを実行します。これらのコマンドは、実行するためにプロセスを起動する必要がないため、高速です。 (ターミナル ウィンドウに「help」と入力すると、Bash ビルトインのリストが表示されます。)
プロセスはフォアグラウンドで実行することができ、その場合、完了するまでターミナルを引き継ぐことも、バックグラウンドで実行することもできます。バックグラウンドで実行されるプロセスはターミナル ウィンドウを支配しないため、ターミナル ウィンドウで作業を続けることができます。少なくとも、画面出力を生成しない限り、ターミナル ウィンドウを支配することはありません。
厄介な例
単純な ping トレースの実行 を開始します。 How-To Geek ドメインに ping を送信します。これはフォアグラウンド プロセスとして実行されます。
ターミナル ウィンドウを下にスクロールすると、期待どおりの結果が得られます。 ping の実行中はターミナル ウィンドウで他の操作を行うことはできません。コマンドを終了するには、Ctrl+C を押します。
Ctrl+C
Ctrl+C の目に見える効果がスクリーンショットで強調表示されています。 ping は短い概要を表示して停止します。
それを繰り返しましょう。ただし、今回は Ctrl+C の代わりに Ctrl+Z を押します。タスクは終了しません。バックグラウンドタスクになります。ターミナル ウィンドウの制御が返されます。
Ctrl+Z
Ctrl+Z を押したときの目に見える効果がスクリーンショットで強調表示されています。
今度はプロセスが停止されたと言われます。停止は終了を意味しません。一時停止標識にある車のようなものです。スクラップして捨てたわけではありません。それはまだ道路上にあり、静止して出発を待っています。このプロセスはバックグラウンド ジョブになりました。
jobs コマンドは、現在の端末セッションで開始された ジョブを一覧表示します 。また、ジョブは (必然的に) プロセスであるため、ps コマンドを使用してそれらを確認することもできます。両方のコマンドを使用して、その出力を比較してみましょう。 T オプション (ターミナル) オプションを使用して、このターミナル ウィンドウで実行されているプロセスのみを一覧表示します。 T オプションではハイフン – を使用する必要がないことに注意してください。
仕事
PST
jobs コマンドは次のことを示します。
- [1]: 角括弧内の数字はジョブ番号です。ジョブ制御コマンドでジョブを制御する必要がある場合、これを使用してジョブを参照できます。
- +: プラス記号 + は、特定のジョブ番号を指定せずにジョブ制御コマンドを使用した場合に、これが実行されるジョブであることを示します。これはデフォルト ジョブと呼ばれます。デフォルトのジョブは常に、ジョブのリストに最後に追加されたジョブです。
- 停止中: プロセスは実行されていません。
- ping www..com: プロセスを起動したコマンド ライン。
ps コマンドは次のことを示します。
- PID: プロセスのプロセス ID。各プロセスには一意の ID があります。
- TTY: プロセスが実行された疑似テレタイプ (ターミナル ウィンドウ)。
- STAT: プロセスのステータス。
- TIME: プロセスによって消費された CPU 時間の量。
- COMMAND: プロセスを起動したコマンド。
以下は STAT 列の一般的な値です。
- D: 中断されないスリープ。プロセスは待機状態にあり、通常は入力または出力を待っており、中断することはできません。
- 私:アイドルです。
- R: 走っています。
- S: 中断可能なスリープ。
- T:ジョブ制御信号により停止しました。
- Z: ゾンビプロセス。プロセスは終了されましたが、親プロセスによって「クリーンダウン」されていません。
STAT 列の値の後に、次の追加インジケーターのいずれかを続けることができます。
- <: 優先度の高いタスク (他のプロセスにとって好ましくない)。
- N: 優先度が低い (他のプロセスに優しい)。
- L: プロセスにはメモリにロックされたページがあります (通常はリアルタイム プロセスによって使用されます)。
- s:セッションリーダー。セッション リーダーは、プロセス グループを起動したプロセスです。シェルはセッションリーダーです。
- l: マルチスレッドプロセス。
- +: フォアグラウンドプロセス。
Bash の状態が Ss であることがわかります。大文字の「S」は、Bash シェルがスリープ状態であり、割り込み可能であることを示します。必要に応じてすぐに対応します。小文字の「s」は、シェルがセッション リーダーであることを示します。
ping コマンドの状態は T です。これは、ping がジョブ制御信号によって停止されたことを示します。この例では、それを背景に置くために使用した Ctrl+Z です。
ps T コマンドの状態は R (実行中) です。 + は、このプロセスがフォアグラウンド グループのメンバーであることを示します。したがって、 ps T コマンドがフォアグラウンドで実行されます。
bg コマンド
bg コマンドはバックグラウンドプロセスを再開するために使用されます。ジョブ番号の有無にかかわらず使用できます。ジョブ番号を指定せずに使用すると、デフォルトのジョブが前面に表示されます。プロセスは引き続きバックグラウンドで実行されます。入力を送信することはできません。
bg コマンドを発行すると、ping コマンドが再開されます。
バックグラウンド
ping コマンドが再開され、ターミナル ウィンドウにスクロール出力が再度表示されます。再起動されたコマンドの名前が表示されます。これはスクリーンショットで強調表示されています。
しかし、問題があります。タスクはバックグラウンドで実行されており、入力を受け入れません。では、どうすればそれを止められるのでしょうか? Ctrl+C では何も起こりません。入力するとそれが表示されますが、バックグラウンド タスクはそれらのキーストロークを受け取らないため、楽しそうに ping を送り続けます。
実際、私たちは今、奇妙な混合モードにいます。ターミナル ウィンドウに入力することはできますが、入力した内容は ping コマンドからのスクロール出力によってすぐに押し流されてしまいます。入力した内容はすべてフォアグラウンドで有効になります。
バックグラウンド タスクを停止するには、それをフォアグラウンドに移動してから停止する必要があります。
fg コマンド
fg コマンドは、バックグラウンド タスクをフォアグラウンドに移動します。 bg コマンドと同様に、ジョブ番号の有無にかかわらず使用できます。ジョブ番号とともに使用すると、特定のジョブで動作することになります。ジョブ番号なしで使用した場合は、バックグラウンドに送信された最後のコマンドが使用されます。
fg と入力すると、ping コマンドがフォアグラウンドに表示されます。入力した文字は ping コマンドの出力と混同されますが、通常どおりコマンド ラインに入力されたかのようにシェルによって操作されます。実際、Bash シェルの観点からは、まさにそれが起こっていることになります。
フロム
これで、ping コマンドが再びフォアグラウンドで実行されるようになったので、Ctrl+C を使用してコマンドを強制終了できます。
Ctrl+C
正しいシグナルを送る必要がある
それはあまりきれいではありませんでした。明らかに、バックグラウンドでプロセスを実行することは、プロセスが出力を生成せず、入力を必要としない場合に最も効果的です。
しかし、面倒かどうかにかかわらず、この例では次のことが実現されました。
- プロセスをバックグラウンドに置く。
- プロセスをバックグラウンドで実行状態に復元します。
- プロセスをフォアグラウンドに戻します。
- プロセスを終了します。
Ctrl+C および Ctrl+Z を使用すると、プロセスにシグナルが送信されます。これらは、kill コマンドを使用する 簡単な方法 です。 kill が送信できる シグナルは 64 種類 あります。それらをリストするには、コマンドラインで kill -l を使用します。 kill だけがこれらのシグナルの発生源ではありません。それらの一部は、システム内の他のプロセスによって自動的に生成されます。
ここでは、一般的に使用されるもののいくつかを紹介します。
- SIGHUP: シグナル 1。プロセスが実行されているターミナルが閉じられると、プロセスに自動的に送信されます。
- SIGINT: シグナル 2。Ctrl+C を押したプロセスに送信されます。プロセスは中断され、終了するように指示されます。
- SIGQUIT: シグナル 3。ユーザーが終了シグナル Ctrl+D を送信した場合にプロセスに送信されます。
- SIGKILL: シグナル 9。プロセスはすぐに強制終了され、完全に終了しようとしません。プロセスは正常に終了しません。
- SIGTERM: シグナル 15。これは、kill によって送信されるデフォルトのシグナルです。標準的なプログラム終了信号です。
- SIGTSTP: シグナル 20。Ctrl+Z を使用するとプロセスに送信されます。プロセスを停止し、バックグラウンドに置きます。
キーの組み合わせが割り当てられていないシグナルを発行するには、kill コマンドを使用する必要があります。
さらなるジョブ制御
Ctrl+Z を使用してバックグラウンドに移動したプロセスは、停止状態になります。再度実行を開始するには、bg コマンドを使用する必要があります。実行中のバックグラウンド プロセスとしてプログラムを起動するのは簡単です。コマンドラインの最後にアンパサンド & を追加します。
バックグラウンド プロセスがターミナル ウィンドウに書き込みを行わないことが最善ですが、書き込みを行う例を使用します。スクリーンショットに参照できるものが必要です。このコマンドは、バックグラウンド プロセスとして無限ループを開始します。
真実である一方で、 「How-To Geek Loop Process」をエコーします。睡眠3;終わり &
プロセスのジョブ番号とプロセス ID ID が通知されます。ジョブ番号は 1、プロセス ID は 1979 です。これらの識別子を使用してプロセスを制御できます。
無限ループの出力がターミナル ウィンドウに表示され始めます。前と同様にコマンド ラインを使用できますが、発行したコマンドはループ プロセスからの出力に散在されます。
ls
プロセスを停止するには、ジョブを使用してジョブ番号を思い出させてから、kill を使用します。
jobs は、プロセスがジョブ番号 1 であることを報告します。kill でその番号を使用するには、その番号の前にパーセント記号 % を付ける必要があります。
仕事
%1を殺す
kill は SIGTERM シグナル (シグナル番号 15) をプロセスに送信し、プロセスが終了されます。次に Enter キーを押すと、ジョブのステータスが表示されます。プロセスが「終了」としてリストされます。プロセスが kill コマンドに応答しない場合は、さらにレベルを上げることができます。 kill を SIGKILL で使用し、シグナル番号 9 を指定します。kill コマンドとジョブ番号の間に数字 9 を入れるだけです。
9 %1 を殺す
私たちが取り上げてきたこと
- Ctrl+C: SIGINT (シグナル 2) をプロセスに送信し (プロセスが入力を受け入れている場合)、終了するように指示します。
- Ctrl+D: SISQUIT (シグナル 3) をプロセスに送信し (プロセスが入力を受け入れている場合)、終了するように指示します。
- Ctrl+Z: SIGSTP、シグナル 20 をプロセスに送信し、プロセスを停止 (サスペンド) してバックグラウンド プロセスになるように指示します。
- ジョブ: バックグラウンド ジョブをリストし、そのジョブ番号を表示します。
- bg job_number: バックグラウンド プロセスを再起動します。ジョブ番号を指定しない場合は、バックグラウンド タスクに変換された最後のプロセスが使用されます。
- fg job_number: バックグラウンド プロセスをフォアグラウンドに移行し、再起動します。ジョブ番号を指定しない場合は、バックグラウンド タスクに変換された最後のプロセスが使用されます。
- コマンドライン &: コマンド ラインの末尾にアンパサンド & を追加すると、そのコマンドがバックグラウンド タスク、つまり実行中のタスクとして実行されます。
- kill %job_number: SIGTERM (シグナル 15) をプロセスに送信してプロセスを終了します。
- kill 9 %job_number: SIGKILL (シグナル 9) をプロセスに送信し、プロセスを突然終了します。





