フォアグラウンドプロセスを否認する私の方法は、あまりにも多くの労力を要します。
zsh
のフォアグラウンドにプロセスがあるとします。 disown
したいので、プロセスにSIGHUP
を送信せずにシェルを閉じることができます。
現時点では、私は Ctrl+z バックグラウンドに移動してプロセスを一時停止してから
$ disown
disown: warning: job is suspended, use `kill -CONT -32240' to resume
$ kill -CONT -32240
$
—その後ターミナルを閉じることができます。
どうすればそれを自動化できますか?理想的には、押すことができるようになりたいです Ctrl+j または、実行中のプロセスをすぐに否認するもの。または、2番目に良いのは、プロセスが一時停止されたら、プロセスの所有権を剥奪し、SIGCONT
する単一のコマンドを実行できるようにすることです。
フォアグラウンドプロセスを否認するためのグローバルキーバインドを持つことは不可能です。キーストロークは、シェルではなくフォアグラウンドプロセスによって受信されます。最初にそれを一時停止する必要があります Ctrl+z あなたがそれを否認したいなら。
ただし、高速化するzshオプションがあることがわかりました所有権を剥奪して続行:setopt AUTO_CONTINUE
を使用すると、disown
は自動的にSIGCONT
も送信します。
したがって、C-z
disown
に下げることができます。
を押すと Ctrl+Z 端末では、これにより、フォアグラウンドプロセスグループがシグナルSIGTSTPを受信します(端末がクックモードであり、デフォルトのキーバインディングが設定されていると想定)。プロセスがSIGTSTPのシグナルハンドラーを設定していない場合、これによりプロセスが一時停止されます(プロセスがシグナルハンドラーを設定している場合でも、通常、プロセスは一時停止する前に少量の処理しか実行しません)。プロセスが強制終了、一時停止、または再開されると、その親はSIGCHLDシグナルを介して通知されます。これにより、シェルは新しいプロンプトと、おそらく[1] + 1234 suspended foo
のようなメッセージを表示します。情報の流れは
キー→一時停止→シェル
ではなく
キー→シェル→一時停止
したがって、別の反応を構成することはできません Ctrl+Z。
SIGCHLDにトラップを設定できますが、ジョブが現在のフォアグラウンドジョブである場合、トラップは実行されません。ほとんどの場合、これは、フォアグラウンドジョブが終了したときではなく、バックグラウンドジョブが終了したときにのみトラップが実行されることを意味します。しかし、それはまた、前景の仕事の中断に反応できないことを意味します。
ジョブの状態を前回のprecmd
の実行で保存された状態と比較する、precmd
フックを設定することで、バックグラウンドジョブの変更に間接的に対応できます。しかし、それで何ができるかわかりません。サスペンドキーは1つしか存在できないため、プロセスが一時停止、バックグラウンド、または非所有のいずれであるかを知るために、追加情報が必要です。
を押すようにzshを設定しました Ctrl+Z 空のプロンプトで、現在のジョブを背景にします。これで押すことができます Ctrl+Z 2回実行して、前景のジョブをバックグラウンドに配置します。
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
必要に応じて、disown
を呼び出すようにすることもできます。またはあなたは3分の1を手配することができます Ctrl+Z 次のテストされていない変更を加えてdisown
を呼び出します。
fancy-ctrl-z () {
if [[ $#BUFFER -eq 0 ]]; then
if (($fancy_ctrl_z_already_bg)); then
disown
else
bg
fancy_ctrl_z_already_bg=1
fi
zle redisplay
else
zle Push-input
fi
}
zle -N fancy-ctrl-z
bindkey '^Z' fancy-ctrl-z
fancy_ctrl_z_precmd () {
fancy_ctrl_z_already_bg=0
}
precmd_functions+=fancy_ctrl_z_precmd