Linux および Unix システム上のソフトウェア割り込みは信号によって行われます。 Linux シグナルにはさまざまなものがありますが、SIGINT、SIGTERM、および SIGKILL などのいくつかは際立っていて、理解して知っておくことが重要です。仕組みは次のとおりです。
Linux シグナル とは何ですか?
私たちは皆、赤信号は歩行や運転を停止しなければならないことを意味すると理解しています。同様に、Linux および Unix システムでは、実行中のプログラムまたはサービスにシグナルを渡して対話することができます。たとえば、次のコマンドを発行するだけで赤信号の標識をプログラムに送信できます。
SIGTERM
信号。
赤信号と同じように、人は信号が赤のときに歩き続けるか車を運転し続けるかを選択する可能性があります。それは関係者全員にとって安全なアイデアではないかもしれませんが、
SIGTERM
プロセスにシグナルを送信すると、まさにそれが行われます。プロセス/プログラムはそのような信号を無視することを選択する場合があります。
基本的な Linux シグナルにはすべて番号 (1 ~ 30+) が付いています。しばらくすると、熟練した Linux ユーザーは通常、これらの 1 つ以上を理解できるようになります。たとえば、
SIGTERM
信号は番号 15 と一致し、信号 9 (
SIGKILL
) は、プロセスを強制的に終了できるため、最もよく知られているものと思われます。
SIGTERM
赤信号の例。
ここではメイン画面が表示されます
htop
(この便利なユーティリティは次のように入力してインストールできます)
sudo apt install htop
Ubuntu/Mint、または
sudo yum install htop
RedHat/Centos/Fedora 上) に多数の終了信号とその他のシグナル (リストの下部、合計 37 個あります) が含まれており、右側で事前に選択したプロセスに送信できます。カーソルを上下に押してプロセスを選択し、F9 を使用してシグナルを送信できます。
シグキル&シグターム
この名前は少し不吉に聞こえるかもしれませんが、プロセス終了の一般的な Linux 用語は、プロセスを「強制終了」することです。一般的に言えば、プロセスを終了したいのは、
-9
(
SIGKILL
) そのようなプロセス/プログラムがハングしている場合にシグナルを送ります。プロセスやプログラムについて話すときは、その言葉を自由に置き換えることができることに注意してください。基本的に、プロセスとは、 PID (プロセス識別子) が与えられた実行中のプログラム (またはサービス) です。
を使用して実行中のバックグラウンド プロセスを終了する例を見てみましょう。
SIGKILL
実行中のプロセスに信号を送ります。説明したように注意してください
SIGKILL
これはむしろ破壊的であり、プロセスがシグナルに対して何をしたいかに関係なく、プロセスを終了させます。多くの信号はプロセスによってキャプチャおよびリダイレクトできますが、それができない信号もあります。
ここで私たちは始めました
sleep 1800
バックグラウンドで(使用して)
&
コマンドの最後)、最初の (
[1]
) バックグラウンドプロセスによる
PID 574660
。その後、次を使用してそのバックグラウンド プロセスを強制終了しました。
kill -9 574660
、 どこ
-9
を意味する
SIGKILL
。
プロセスはすぐに終了しますが、終了メッセージは表示されません(バックグラウンドプロセス)
1
殺された、つまり、
[1] + Killed
) メッセージが表示される前にコマンド プロンプトが戻るため、つまり、コマンド ラインに戻る方が、プロセスの終了などよりも速い操作でした。
PID を grep してプロセス リストを確認します。
ps -ef | grep 574660
。いくつかの出力がありますが、表示されている出力は実行中のもののみです。
grep
指示;の
sleep
プロセスはすでに終了しています。
同じように評価しましょう
SIGTERM
、つまり
kill -15 ${PID}
どこ
${PID}
は終了したいプロセスです。
(上で説明したように) 終了メッセージをトリガー/表示するには Enter キーを押す必要がありました。プログラムが再び正しく終了したことがわかります。ただし、今回は、この特定の例では表示されませんが (続きを読んでください!)、内部的には
sleep
プログラムコードの場合、状況は少し異なります。
この場合(使用
-15
つまり
SIGTERM
プロセスを終了します)、
sleep
プロセスは通知を受け、内部でシグナルを処理する機会を得ました。その後、自己終了、信号の無視、またはコードに組み込まれたその他のアクションによって応答する可能性があります。終了信号や出力をチェックすることで、これが正しいことを証明することもできます。
ここでプロセスを開始しました
sleep 2000
2 回実行し、別のシェル/ターミナル セッションを使用してプログラムを終了します。初めて私たちが利用したのは、
kill -9
そして2回目に利用したとき
kill -15
を止めるために
sleep
プロセス。
出力がどのように返されるかがすぐに分かります
Killed
最初に (
kill -9
アクション) インスタンス。 2 回目の試行の場合 (使用
kill -15
)、出力が表示されます
Terminated
その代わり;プログラムが自己終了しました。それぞれの終了に続いて、終了信号もチェックしたところ、終了コードが異なることがわかりました。
何でこれが大切ですか?より大きなプログラムを検討してください。この例では、単純なコマンドを終了しただけです。
sleep
指示。処理されるデータや送受信されるトラフィックなどはありませんでした。
kill -9
データベースサーバーにコマンドを送信します (これには一般的に sudo/root レベルの権限が必要です)?
これにより、次回起動時にデータベースがクラッシュ リカバリ モードに移行することになります。これは、データベース ソフトウェアが知る限り、起こったことは「存在した」後に「何も起こらなかった」だけであるためです。言い換えれば、クラッシュしたのです。代わりに
kill -15
コマンドを実行すると、データベース ソフトウェアは、たとえば、最初に新しいユーザーの接続をブロックし、次に既存のユーザーを切断/終了し、データの書き込みを終了してから最終的に自己終了するなど、制御されたシャットダウンを実行できた可能性があります。
キーボードシーケンスによる Linux 信号の送信
を送信するたびに、
CTRL+c
たとえばターミナルなどで実行中のプログラムへのキー シーケンス。
SIGINT
送信されますか?信頼できる場所に戻りましょう
sleep
コマンドを実行してこれをテストします。
ここから始めました
sleep
もう一度押して、キーボードの組み合わせを押しました
CTRL+c
。プログラムは終了したか、より適切には 中断されました。
SIGINT
送信された信号。終了コードを要求し、終了コードが以前のシグナルと異なることを再度確認します。
スリープの場合、この終了コードは常に送信された信号と一致しますが、すべての信号がカバーされているわけではない可能性があることに注意してください。つまり、使用するときは、
CTRL+c
コマンドラインでは、終了コードは常に次のようになります。
130
、
137
で殺されたとき
kill -9
、 そして
143
いつ
kill -15
使われた。
コマンドの終了コードをテストするには、
$?
変数。前のコマンドの終了コードを保持します (新しいコマンドを開始していない限り)。特定の状況における特定のコマンドの終了コード、および/またはそのコマンドに送信された特定のシグナルの結果としての終了コードを知ることは、他のプロセスなどを処理するソリューションをスクリプト化するときに役立ちます (これは、特に多くのシェル スクリプトの場合に当てはまります)。サーバーまたは自動化された環境を管理する場合)。
もう 1 つのよく使用されるキーボード シーケンスは次のとおりです。
CTRL+z
。これにより、
SIGTSTP
信号、
suspend
(たとえば)
'fg'
同じプロセスに対してコマンドが発行され、プロセスがフォアグラウンドに戻ります。
プロセス管理の詳細については、 「Bash プロセス終了ハック」 を参照してください。
まとめ
この記事では、最も重要な Linux シグナルと、それらを Linux または Unix 環境で実際に使用する方法について検討しました。基本的な Linux シグナルを理解すると、たとえば、プロセスがハングして終了する必要がある場合など、日常的な Linux の使用と管理に役立ちます。
kill -9
。今後の記事では、
trap
Bash スクリプト内からコマンドを実行すると、そのようなシグナルが発行されたときに実行されるカスタム プロシージャを定義できます。
この記事を読んで気に入ったら、 「 Bash オートメーションとスクリプトの基礎 」 から始まる Bash オートメーション シリーズをご覧ください。シリーズの 3 回目の記事では、この記事の前半で触れたバックグラウンド プロセス管理についても説明します。





