web-dev-qa-db-ja.com

シェルSIGKILLキーバインド

SIGKILLを現在のフォアグラウンドジョブに送信するようにキーバインディングを設定するにはどうすればよいですか?私はすでにそれを知っています Ctrl+CSIGINTであり、 Ctrl+\SIGQUITです。もっと厳しいオプションをお願いします。

これについて真剣に勧められないことはありますか?

21
drewrobb

お勧めできないかどうか、それは実際には不可能です:

の Ctrl+ [?]キーバインドは実際にはシェルではなくttyドライバーによって処理されます。これは、フォアグラウンドで実行されているプロセスがある限り、端末の入力と出力が直接プロセスに転送されるためです。シェルはあなたのキー操作に応じることはできません(または見ることさえできません)。

現在割り当てられているリストを取得できます Ctrl+ [?]キーの組み合わせ stty -a ;ただし、intr(SIGINT、通常は Ctrl+Cquit(SIGQUIT、通常は Ctrl+\)とsusp(SIGSUSP、通常は Ctrl+Z)実際のUNIX信号に対応します。 (たとえば、killはSIGKILLを送信しませんが、現在の入力を削除します。)

残念ながら、プロセスで無効にできない2つの信号(SIGKILLとSIGSTOP)の1つを送信する方法はないため、上記の3つの信号がすべて効果がない場合は、他の方法を使用する必要があります(たとえば別のシェル)フォアグラウンドプロセスを強制終了します。

(実際には、フォアグラウンドプロセスは、3つの信号すべてをキャッチすることに加えて、最初にttyを「raw」モードに設定することにより、特別なキーの組み合わせを無効にすることもできます。たとえば、SSHはこれを実行します–これがリレーの方法です地元で押された Ctrl+C リモートホストへ)。

28
lxgr

はい、お勧めできないことがあります。 SIGINTからSIGKILL信号に直接ジャンプしています。核オプションを使用する前に、SIGHUPまたはSIGTERMシグナルを送信することを検討しながら、 他の人がするように をお勧めします。次に、これをキーバインドとして使用することはお勧めできません。つまり、ZLEがアクティブで、シェルが対話的に入力を求めている場合にのみ機能し、コマンドの実行中は機能しません。 (そのためには、wouldシェルではなく端末を構成する必要があり、SIGTERMをPOSIXで指定された動作の拡張機能として送信することを実装する端末回線規則が必要です。)

その点では、ターミナルではなくシェルラインエディターのキーバインディングについて尋ねていることに誰も気づいていないようです。質問の最初の部分に回答するには、次のようにします。

シェル関数を設定して、信号を「現在の」ジョブに送信します。

_function terminate-current-job() { kill -s TERM %+ ; }
_

次に、このシェル関数を呼び出すZLEユーザー定義ウィジェットを作成します。

_zle -N terminate-current-job terminate-current-job
_

次に、最後に、そのウィジェットを選択したキーにバインドします。

_bindkey "^/" terminate-current-job
_
3
JdeBP