comment on this answer of another question で、コメンターは言います:
絶対に必要でない限り、kill-9を使用しないでください! SIGKILLをトラップできないため、強制終了されたプログラムはシャットダウンルーチンを実行できません。一時ファイルを消去します。最初にHUP(1)、次にINT(2)、次にQUIT(3)を試してください
SIGKILL
については原則的に同意しますが、残りは私にとってニュースです。 kill
によって送信されるデフォルトのシグナルがSIGTERM
であるとすると、それは任意のプロセスの正常なシャットダウンのために最も一般的に期待されるシグナルであると予想されます。また、デーモンに「設定ファイルを再読み込み」するなど、終了しない理由で使用されるSIGHUP
を見てきました。そして、SIGINT
(通常Ctrl-Cで取得するのと同じ割り込み?)は、本来サポートされているほど広くサポートされていないか、かなり不自然に終了しているように思えます。
SIGKILL
が最後の手段であるとすると、どのシグナルで、どの順序で、次の目的で任意のプロセスに送信する必要がありますか可能な限り正常にシャットダウンしますか?
可能であれば、裏付けとなる事実(個人の好みや意見を超えて)または参考文献で回答を実証してください。
注:bash/Cygwinの検討を含むベストプラクティスに特に興味があります。
Edit:これまでのところ、誰もINTやQUITについて言及していないようで、HUPについての言及は限られています。これらを整然としたプロセス殺害に含める理由はありますか?
SIGTERMはアプリケーションに終了するよう指示します。他のシグナルは、シャットダウンとは無関係ですが、同じ結果になる場合があることをアプリケーションに伝えます。それらを使用しないでください。アプリケーションをシャットダウンする場合は、それを伝えます。誤解を招くような信号を与えないでください。
プロセスを終了するスマートな標準方法は、HUP、INT、TERM、KILLなどの多数のシグナルを送信することだと考える人もいます。ばかげてる。終了の正しいシグナルはSIGTERMであり、SIGTERMがすぐにプロセスを終了しない場合は、必要に応じて、アプリケーションがシグナルの処理を選択したためです。つまり、すぐに終了しないという非常に正当な理由があるということです。つまり、クリーンアップ作業が必要です。そのクリーンアップ作業を他の信号で中断した場合、メモリからまだディスクに保存されていないデータ、ハングしているクライアントアプリケーション、または実際にデータ破損である「センテンス」を中断しているかどうかはわかりません。
シグナルの実際の意味の詳細については、sigaction(2)を参照してください。 「デフォルトアクション」と「説明」を混同しないでください。これらは同じものではありません。
SIGINTは、プロセスの対話型「キーボード割り込み」を通知するために使用されます。一部のプログラムは、端末ユーザーの目的のために特別な方法で状況を処理する場合があります。
SIGHUPは、端末が消え、プロセスを見なくなったことを通知するために使用されます。それだけです。一般に、端末なしでは操作が意味をなさないため、一部のプロセスは応答してシャットダウンすることを選択します。また、構成ファイルの再チェックなどの他の処理を選択するプロセスもあります。
SIGKILLは、カーネルからプロセスを強制的に削除するために使用されます。実際にはプロセスへのシグナルではなく、カーネルによって直接解釈されるという意味で特別です。
SIGKILLを送信しないでください。 SIGKILLはスクリプトによって送信されることはありません。アプリケーションがSIGTERMを処理する場合、クリーンアップに1秒かかることがあり、1分かかることがあります1時間かかることがあります。アプリケーションが終了する準備ができる前に何をしなければならないかによって異なります。アプリケーションのクリーンアップシーケンスを「が想定する」というロジックは、X秒後にショートカットまたはSIGKILLを実行する必要があるため、単なる間違いです)。
アプリケーションがSIGKILLを終了する必要がある理由は、クリーンアップシーケンス中に何かがバグアウトした場合だけです。その場合、ターミナルを開いて手動でSIGKILLできます。それとは別に、SIGKILLをするもう1つの理由は、[〜#〜] [-#〜]それを防ぐためです自分自身をきれいにすることから。
世界の半分は5秒後にSIGKILLを盲目的に送信しますが、それでもやるべきことは恐ろしく間違っています。
ショートアンサー:SIGTERM
、30秒後、SIGKILL
を送信します。つまり、SIGTERM
を送信し、少し待機します(プログラムごとに異なる場合がありますが、システムをよく知っているかもしれませんが、5〜30秒で十分です。マシンをシャットダウンすると、自動的に待機します。急いでいるのはなぜですか?)、SIGKILL
を送信します。
合理的な回答:SIGTERM
、SIGINT
、SIGKILL
これで十分です。プロセスはおそらくSIGKILL
の前に終了しますvery。
ロングアンサー:SIGTERM
、SIGINT
、SIGQUIT
、SIGABRT
、SIGKILL
これは不要ですが、少なくともメッセージに関するプロセスを誤解させないでください。これらすべてのシグナルdoは、プロセスが実行中の処理を停止して終了することを意味します。
この説明からどんな答えを選んでも、それを覚えておいてください!
他の何かを意味するシグナルを送信すると、プロセスはそれを非常に異なる方法で処理する可能性があります(一方で)。一方、プロセスがシグナルを処理しない場合、何を送信しても問題ありません。プロセスはとにかく終了します(もちろん、デフォルトのアクションが終了する場合)。
ですから、あなたは自分自身をプログラマーとして考えなければなりません。何かと接続するプログラムを終了するためにSIGHUP
の関数ハンドラーをコーディングしますか、それともループしてもう一度接続しようとしますか?それがここの主な質問です!そのため、意図したことを意味する信号を送信することが重要です。
ほとんど愚かな長い答え:
以下の表には、関連する信号と、プログラムがそれらを処理しない場合のデフォルトのアクションが含まれています。
あなたが本当にすべてを試してみる必要がある場合(それはここではなく、合理的な答えを使用することをお勧めします)テーブルが引き起こす破壊に関して順序付けられていると言うのは楽しいでしょうが、それは完全ではありませんtrue)。
アスタリスク(*)の付いたシグナルは、[〜#〜] not [〜#〜]を推奨します。これらについての重要なことは、それが何をするようにプログラムされているかを決して知らないかもしれないということです。特にSIGUSR
!それは黙示録を開始するかもしれません(それはプログラマが望むことを何でもするための無料のシグナルです!)。しかし、処理されない場合[〜#〜] or [〜#〜]、まれに終了するように処理された場合、プログラムは終了します。
表では、終了してコアダンプを生成するデフォルトオプションの信号は、SIGKILL
の直前に残ります。
Signal Value Action Comment
----------------------------------------------------------------------
SIGTERM 15 Term Termination signal
SIGINT 2 Term Famous CONTROL+C interrupt from keyboard
SIGHUP 1 Term Disconnected terminal or parent died
SIGPIPE 13 Term Broken pipe
SIGALRM(*) 14 Term Timer signal from alarm
SIGUSR2(*) 12 Term User-defined signal 2
SIGUSR1(*) 10 Term User-defined signal 1
SIGQUIT 3 Core CONTRL+\ or quit from keyboard
SIGABRT 6 Core Abort signal from abort(3)
SIGSEGV 11 Core Invalid memory reference
SIGILL 4 Core Illegal Instruction
SIGFPE 8 Core Floating point exception
SIGKILL 9 Term Kill signal
その後、私はこれについてほぼ愚かな長い答えを提案します:SIGTERM
、SIGINT
、SIGHUP
、SIGPIPE
、SIGQUIT
、SIGABRT
、SIGKILL
そして最後に、
間違いなく愚かな長い長い答え:
自宅でこれを試さないでください。
SIGTERM
、SIGINT
、SIGHUP
、SIGPIPE
、SIGALRM
、SIGUSR2
、SIGUSR1
、SIGQUIT
、SIGABRT
、SIGSEGV
、SIGILL
、SIGFPE
、および何も機能しない場合は、SIGKILL
。
SIGUSR2
はSIGUSR1
の前に試行する必要があります。これは、プログラムが信号を処理しない場合のほうが良いからです。そして、それらのうちの1つだけを処理する場合、SIGUSR1
を処理する可能性がはるかに高くなります。
ところで、KILL:他の答えが述べているように、SIGKILL
をプロセスに送信することは間違っていません。さて、shutdown
コマンドを送信するとどうなりますか? SIGTERM
およびSIGKILL
のみを試行します。なぜそうだと思いますか?そして、非常にshutdown
コマンドがこれら2つだけを使用する場合、なぜ他の信号が必要なのですか?
さて、長い答えに戻って、これはニースのワンライナーです:
for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done
信号間で30秒間スリープします。他にonelinerが必要なのはなぜですか? ;)
また、推奨:合理的な回答からの信号15 2 9
のみで試してください。
safety:準備ができたら2番目のecho
を削除します。 onlinersのdry-run
と呼びます。常にテストに使用してください。
kill killfullyfully
実際、私はこの質問に非常に興味をそそられ、それを行うための小さなスクリプトを作成することにしました。こちらからダウンロード(クローン)してください:
Killgracefully repository へのGitHubリンク
SIGTERM
は実際にアプリケーションにメッセージを送信することを意味します:「あなたはとても親切で自殺しますか」。アプリケーションによってトラップおよび処理され、クリーンアップおよびシャットダウンコードを実行できます。
SIGKILL
はアプリケーションによってトラップできません。アプリケーションは、クリーンアップの機会なしにOSによって強制終了されます。
最初にSIGTERM
を送信し、しばらくスリープしてからSIGKILL
を送信するのが一般的です。
ここでのすべての議論では、コードは提供されていません。私の見解は次のとおりです。
#!/bin/bash
$pid = 1234
echo "Killing process $pid..."
kill $pid
waitAttempts=30
for i in $(seq 1 $waitAttempts)
do
echo "Checking if process is alive (attempt #$i / $waitAttempts)..."
sleep 1
if ps -p $pid > /dev/null
then
echo "Process $pid is still running"
else
echo "Process $pid has shut down successfully"
break
fi
done
if ps -p $pid > /dev/null
then
echo "Could not shut down process $pid gracefully - killing it forcibly..."
kill -SIGKILL $pid
fi
HUPは私にとってはごみのように聞こえます。デーモンに設定を再読み込みさせるために送信します。
SIGTERMは傍受できます。デーモンは、そのシグナルを受け取ったときに実行するクリーンアップコードを持っているだけです。 SIGKILLに対してはできません。したがって、SIGKILLを使用すると、デーモンの作成者にオプションを与えることはできません。
詳細については Wikipedia