陷阱ctrl-c,运行一个函数,但不要退出子进程?

时间:2017-10-24 23:25:13

标签: bash scala

它实际上是一个从bash脚本作为子进程启动的Scala REPL。

我想更改ctrl-c的功能,但不会干扰scala REPL。

function ctrl_c_handler() {
  # do some stuff, but don't exit
}

trap ctrl_c_handler SIGINT

scala

有趣的是忽略信号工作正常trap '' SIGINT。 ctrl-c无法杀死我的REPL,但如果我实际附加了一个函数,我就无法阻止该进程退出。

有哪些选择? scala REPL需要在前台。 ctrl_c_handler可以启动后台进程。

1 个答案:

答案 0 :(得分:1)

一旦子进程启动,Bash既不会看到终端输入也不会看到终端生成的信号(如SIGINT),因为子进程成为终端前台进程组的唯一成员。一旦子进程终止,Bash只会再次看到终端。

忽略bash中的SIGINT,因为子进程继承了尚未分配信号处理程序的信号的处置。

您可以使用stty将SIGINT重新分配给其他键盘符号(或无键盘符号);子进程也将继承该设置。这将导致ctrl-C成为普通字符,因此它不会中断子进程。不幸的是,它也不会打断bash,所以这不是一个真正的解决方案。

您可以通过创建伪终端(pty)并将子进程附加到伪tty的从属端来创建一个子进程,通过该子进程可以进行更多控制。然后,您可以通过将数据写入pty的主端,将从终端读取的输入传递到子进程,并通过从主端读取并写入终端将子进程的输出传递回终端。在此配置中,您可以在主进程中捕获SIGINT,而不是将其传递给子进程。但是,您几乎肯定需要用某种语言(不一定是C)来编写它,这使您可以访问系统设施;它可能在bash中,但它将是一个非常黑客。请阅读man pty以获取有关从哪里开始的更多信息。