繁体   English   中英

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

[英]How to immediately trap a signal to an interactive Bash shell?

我尝试从一个终端 A 向另一个终端 B 发送信号。两者都运行一个交互式 shell<\/strong> 。

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

$ trap 'source ~/mycommand' SIGUSR1

外壳程序可能只是停留在阻塞读取中,等待命令行输入。 按下Enter键会使处理程序在输入的命令之前执行。 运行非阻塞命令,如wait

$ sleep 60 & wait

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

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

为了触发它,用户必须进行交互。

这是由于readline程序块直到输入换行符所致。 而且没有办法停止读取。

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

该程序可以运行一个完全交互式的外壳程序,并在其最新版本中具有某些功能,可以通过自定义套接字与该外壳程序(或您启动的任何程序)进行通信

要在终端B中启动一个新的运行交互式bash的dtach会话,请执行以下操作:

$ dtach -a /tmp/MySocket bash -i

现在从终端A,我们可以像这样向终端B中的bash会话发送消息:

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

在终端B中,我们现在看到:

$ echo hello
hello

如果我现在在终端A中进行扩展:

$ trap'echo“ cd $(pwd)” | dtach -p / tmp / MySocket'调试

我将两个终端的目录同步

PS:我仍然想知道是否有一种方法可以做到纯正bash

它可能正在缓冲。

作为测试,请尝试安装循环触发器。 在窗口A中:

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

在窗口B中:

 kill -usr1 7316

返回到窗口A中,循环执行回显时, ls触发。 不知道这是否会有所帮助,但这是有的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM