他のいくつかのプログラムを呼び出し、一連のコマンドを実行するbashスクリプトを作成しました。このスクリプトを端末から実行します。次に、スクリプトを強制終了します。
Ctrl + C
を押してもカットされないことがあります。スクリプトが別のプログラムを実行していることがあり、何らかの理由でキル信号が機能しないためだと思います。
ただし、ターミナルウィンドウを閉じると、スクリプトが強制終了されます。
できることはありますか(キーボードの組み合わせ)、それは実際に端末ウィンドウを閉じずに端末ウィンドウを閉じることに似ています(コマンド履歴、現在のディレクトリ、出力履歴などを失いたくない)?
選択肢はほとんどありません。 1つは、スクリプトを停止することです(CtrlZ)、スクリプトのPIDを取得し、プロセスグループに SIGKILL
を送信します。
コマンドがシェルで実行されると、コマンドが開始するプロセスとそのすべての子は同じ process group (この場合、フォアグラウンドプロセスグループ)。このグループのすべてのプロセスに信号を送信するには、プロセスリーダーに送信します。 kill
コマンドの場合、プロセスリーダーは次のように示されます。
kill -PID
ここで、PID
はスクリプトのプロセスIDです。
例:
いくつかのプロセスを起動するスクリプトtest.sh
を考えてください。シェルで実行したとしましょう:
$ ./test.sh
別の端末で、
$ pgrep test.sh
17802
$ pstree -ps `!!`
pstree -ps `pgrep test.sh`
init(1)───sshd(1211)───sshd(17312)───sshd(17372)───zsh(17788)───test.sh(17802)─┬─dd(17804)
├─sleep(17805)
└─yes(17803)
この場合、test.sh
によって作成されたプロセスグループにシグナルを送信するには、次のようにします。
kill -INT -17802
-INT
はSIGINT
の送信に使用されるため、このコマンドは CtrlC ターミナルで。 SIGKILL
を送信するには:
kill -KILL -17802
別の端末を開くことができない場合にのみ、スクリプトを停止する必要があります。可能であれば、pgrep
を使用してPIDを見つけます。
スクリプトが起動するコマンドの1つがSIGINT
をトラップしている可能性があります。 CtrlC 効果がありません。ただし、SIGKILL
はトラップできず、通常はlast-resortオプションです。キルする前にSIGTERM
(-TERM
)を試してみるとよいでしょう。 SIGKILL
もSIGTERM
も、SIGINT
のように キーボードショートカット として設定できません。
スクリプトにShebang行が含まれていない場合、これはすべて意味がありません。 this SO answer :から
通常、親シェルは、同じシェル用にスクリプトが記述されていると推測します(最小限のBourneのようなシェルは/ bin/shでスクリプトを実行し、bashはbashサブプロセスとして実行します)...
このため、スクリプトの実行時に、スクリプトにちなんで名付けられたプロセス(またはコマンドラインでスクリプトの名前を持つプロセス)が見つからず、pgrep
は失敗します。
常にシバンラインを使用してください。
スクリプトに関連付けられているプロセスがわかっている場合は、次を使用してPIDを見つけることができます
ps -A
次に、PID番号を使用して、対応するプロセスを強制終了します。
kill -9 PID_Number
ハリスが言ったように、Kill -9 PID_Number
を実行できますが、htop
と呼ばれるパッケージをインストールして、特定のプロセスを簡単に見つけることができるインタラクティブなプロセスブラウザーを使用することもできます。 htopはプロセスの強制終了もサポートしています。