Quando você pressiona Ctrl + Z em um terminal, isso faz com que o grupo de processos em primeiro plano receba o sinal SIGTSTP (supondo que o terminal esteja no modo cozido e a tecla padrão ligações estão no lugar). Se o processo não definiu um manipulador de sinal para SIGTSTP, isso faz com que o processo seja suspenso (e mesmo que o processo tenha definido um manipulador de sinal, normalmente ele faz apenas uma pequena quantidade de processamento antes de suspender a si mesmo). Quando um processo é morto, suspenso ou retomado, seu pai é notificado por meio de um sinal SIGCHLD; isso é o que faz com que o shell exiba um novo prompt e talvez uma mensagem como [1] + 1234 suspended foo
. O fluxo de informações é
chave → suspensão → shell
e não
chave → shell → suspensão
então você não pode configurar uma reação diferente para Ctrl + Z .
Você pode definir um trap para SIGCHLD, mas o trap não é executado quando o trabalho é o atual trabalho em primeiro plano. Na maioria das vezes, isso significa que a interceptação é executada somente quando um job em background é encerrado, não quando o job em primeiro plano é finalizado. Mas também significa que você não pode reagir à suspensão do trabalho em primeiro plano.
Você pode reagir indiretamente a alterações nas tarefas em segundo plano configurando um gancho precmd
que compara os estados da tarefa com os estados salvos da execução anterior em precmd
. Mas eu não sei o que você poderia fazer com isso: só pode haver uma única chave de suspensão, então você precisa de alguma informação extra para saber se o processo foi feito para ser pausado, com background ou deserdado.
Eu configurei o zsh para que pressionar Ctrl + Z em um prompt vazio faça o background do trabalho atual. Isso me permite pressionar Ctrl + Z duas vezes para colocar o trabalho em primeiro plano em segundo plano com apenas uma pequena suspensão.
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
Você pode chamar disown
se desejar. Ou você poderia organizar um terceiro Ctrl + Z para chamar disown
com a seguinte modificação não testada.
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