如何立即将信号捕获到交互式 Bash shell?

How to immediately trap a signal to an interactive Bash shell?

我尝试从一个终端 A 向另一个终端 B 发送信号。运行 和 交互 shell.

在终端 B,我像这样捕获信号 SIGUSR1 :

$ trap 'source ~/mycommand' SIGUSR1

现在在航站楼 A 中,我发送这样的信号:

$ kill -SIGUSR1 pidOfB

不幸的是,B 没有任何反应。如果我想执行我的命令,我需要切换到 B 并输入新命令或按回车。

我怎样才能避免这个缺点并立即执行我的命令?

编辑:

需要注意的是,我想直接从终端A与终端B中的交互shell进行交互。 出于这个原因,在 subshell 中执行陷阱命令的每个解决方案都不适合我...

此外,终端 B 必须保持交互。

可能正在缓冲。

作为测试,请尝试安装循环触发器。在window答:

{ trap 'ls' USR1; while sleep 1; do echo>/dev/null;done } &
[1] 7316

在window B:

 kill -usr1 7316

回到 window 当循环执行回显时,ls 正在触发。 不知道这是否会有所帮助,但它是有用的。

shell 可能只是卡在阻塞读取中,等待命令行输入。按回车键会导致处理程序在输入的命令之前执行。 运行 非阻塞命令,如 wait:

$ sleep 60 & wait

然后发送信号导致 wait 立即终止,然后是处理程序的输出。

根据答案和我为解决这个问题所做的无数次尝试,我认为不可能在交互式 bash 终端中立即捕获陷阱信号。

要触发它,必须有来自用户的交互。

这是由于 readline 程序阻塞,直到输入换行符。并且无法停止此读取。

我的解决方案是使用 dtach,一个模拟屏幕分离功能的小程序。

这个程序可以 运行 一个完全交互的 shell 并且在它的最后一个版本中提供了一种通过自定义套接字与这个 shell (或你启动的任何程序)进行通信的方式

要在终端 B 中启动一个新的 dtach 会话 运行ning 一个交互式 bash:

$ dtach -a /tmp/MySocket bash -i

现在,我们可以从终端 A 向终端 B 中的 bash 会话发送一条消息,如下所示:

$ echo 'echo hello' | dtach -p /tmp/MySocket

在航站楼 B,我们现在看到:

$ echo hello
hello

如果我现在在航站楼 A 进行扩展:

$陷阱'echo "cd $(pwd)" | dtach -p /tmp/MySocket'调试

我把两个终端的目录同步一下

PS :我仍然想知道是否有办法在纯 bash

中做到这一点

我使用了一个类似的陷阱,这样我就可以定期(从一个单独的 cron 作业)强制所有空闲的 bash 进程执行 'history -a'。我发现如果我捕获 SIGALRM 而不是 SIGUSR1,那么 bash 阻塞读取似乎不是问题:陷阱现在运行,而不是下一次命中 return。我尝试了 SIGINT,但这会导致显示一个烦人的“^C”,然后显示一个新的提示行。我还没有发现使用 SIGALRM 的任何缺点,但也许它们会出现。