我如何才能通过一次按下 Ctrl-Z 和 bg 来使进程在后台继续?

我如何才能通过一次按下 Ctrl-Z 和 bg 来使进程在后台继续?

我遵循这种模式,暂停任务,然后让它按照序列继续执行Ctrl-Z bg

我想知道是否有任何方法可以将其压缩为单次按键?

我的壳是zsh

答案1

Ctrl+序列Z由终端处理,而不是由 shell 处理。(有用的背景:“终端”、“shell”、“tty”和“控制台”之间到底有什么区别?

只有一小部分不可扩展的功能绑定到终端中的键。 你可以自定义按键绑定到这些函数但不添加其他函数。这些函数分为三类:

  • 未提供自己的程序中的命令行版本(规范模式,也称为熟模式(与原始模式相对),在实践中很少使用):文件末尾(eofCtrl+ D),行尾(eolCtrl+ M),删除左侧字符(eraseCtrl+ H),删除左侧单词(weraseCtrl+ W),删除行(killCtrl+ U)。
  • 手动流控制:(+ ),stop(+ )。仅适用于老式串行终端,当终端无法跟上计算机的速度或反之亦然时,会丢失字符。CtrlSstartCtrlQ
  • 信号传输:中断(intrCtrl+ C)、强制退出(quitCtrl+ \)、暂停(Ctrl+ Z)。

有些系统(包括 Linux)扩展了该列表,但我从未见过包含后台运行的系统。请注意,它需要内核中的终端驱动程序和终端仿真器的支持。因此,您必须使用暂停,这会向前台作业发送一个信号传输协议信号。这会触发信号发生器在前台作业领导者的父进程中,通常是 shell。当 shell 收到 SIGCHLD 时,它会调用waitpid弄清楚为什么会收到通知,并且在检测到后台作业被暂停时,它会显示一条通知(例如[1] + 12345 suspended mycommand)和一个新的提示。

您可以对 shell 进行编程,使其SIGCONT向前台作业发送信号。我认为 zsh 没有这样的钩子,您需要修补源代码。而且 zsh 无法知道您是真的想中断程序(哎呀,这个程序可能做错了,让我先暂停它,等我把它理顺)还是让它在后台运行。


Ctrl我所做的是将 zsh 中的+键序列设置Z为将当前作业置于后台 ( %%)。这样,我可以通过按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

答案2

^z ^z 像上面的 zsh 一样在 bash 中也是可以的,尽管它有点笨拙并且我还没有运行它很长时间:

  • 在你的 .inputrc 中包含映射"\C-z": "bg\n"
  • 在 PS0 bash 变量中包含 `$(stty susp ^z)'
  • 在 PROMPT_COMMAND bash 变量中包含“stty susp ^@”

因此,当运行命令时,表示暂停的 ^z 会被打开,而在 bash 提示符下则会被关闭。

答案3

所以我找到了解决方案,虽然不是我想要的,但已经很接近了https://superuser.com/a/161922/35223

在空的命令行上运行 bg(这样 Ctrl+Z Ctrl+Z 会暂停程序并立即在后台恢复它)。

答案4

对于 bash:

将以下行添加到您的 .bashrc 文件:

trap "bg" SIGTSTP

描述:SIGTSTP 信号由终端发出,而不是由 shell 发出。它由终端通过 ctrl-z 发送并由 shell 捕获。上面的命令挂接该信号并执行所需的命令。

相关内容