Ctrl +Z シーケンスは、シェルではなく端末によって処理されます。 (役立つ背景:「ターミナル」、「シェル」、「tty」、「コンソール」の正確な違いは何ですか?)
端末のキーにバインドできるのは、小規模で拡張不可能な機能セットのみです。これらの機能にバインドされたキーはカスタマイズできますが、別の機能を追加することはできません。これらの機能は次の 3 つのカテゴリに分類されます。
- 独自のコマンド ライン エディションを提供しないプログラムのコマンド ライン エディション (canonical モード、cooked モードとも呼ばれます (raw モードと反対に)。実際にはめったに使用しません):end of file (
eof
, Ctrl +D )、行末 (eol
, Ctrl +M )、残りの文字を消去 (erase
, Ctrl +H )、残りの単語を消去 (werase
, Ctrl +W )、行を消去 (kill
, Ctrl +U ). - 手動フロー制御:
stop
(Ctrl +S )、start
(Ctrl +Q )。端末がコンピュータの速度に追いつけない場合、またはその逆の場合に文字がドロップする古いシリアル端末でのみ有用です。 - シグナリング:割り込み (
intr
, Ctrl +C )、強制終了 (quit
, Ctrl +\ )、サスペンド (Ctrl +Z ).
Linux を含む一部のシステムではそのリストが拡張されていますが、バックグラウンド処理を含むシステムは見たことがありません。カーネルの端末ドライバーと端末エミュレーターの両方でサポートが必要になることに注意してください。そのため、フォアグラウンド ジョブに SIGTSTP シグナルを送信するサスペンドを行う必要があります。これにより、フォアグラウンド ジョブのリーダー (通常はシェル) の親プロセスで SIGCHLD がトリガーされます。シェルが SIGCHLD を受け取ると、waitpid
を呼び出します。 通知された理由を把握し、バックグラウンド ジョブが中断されたことを検出すると、通知を表示します (例:[1] + 12345 suspended mycommand
) と新しいプロンプト。
SIGCONT
を送信するようにシェルをプログラムできます。 フォアグラウンド ジョブに通知します。 zsh にはそのためのフックがないと思います。ソース コードにパッチを当てる必要があります。そして、zsh には、あなたが本当にプログラムを中断するつもりだったのか (おっと、このプログラムは間違ったことをしている可能性があります。解決するまで一時停止させてください)、またはバックグラウンドにするつもりだったのかどうかを知る方法はありません。
私がすることは、 Ctrl を設定することです +Z 現在のジョブをバックグラウンドで実行する zsh のキー シーケンス (%%
)。そうすれば、Ctrl を押して、フォアグラウンド ジョブをバックグラウンドに送信できます。 +Z Ctrl +Z .その際、Ctrl を押します。 +Z 現在の入力行が空でない場合 (つまり、サブプロセスから戻ってきたわけではない) に別の便利な処理を行う:現在の入力行を「一時停止」して、別のコマンドを入力できるようにし、その後、中断された行を押し戻します。入力バッファ
fancy-ctrl-z () {
if [[ $#BUFFER -eq 0 ]]; then
bg
zle redisplay
else
zle push-input
fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z
上記の zsh のような ^z ^z は bash で可能ですが、少しぎこちなく、私はこれを長い間実行していません:
- .inputrc にマッピング
"\C-z": "bg\n"
を含めます - PS0 bash 変数に「$(stty susp ^z)」を含めます
- PROMPT_COMMAND bash 変数に「stty susp ^@」を含めます
そのため、サスペンドの ^z は、コマンドの実行時にオンになり、bash プロンプトではオフになります。