为了账号安全,请及时绑定邮箱和手机立即绑定

从交互式 go cli 中终止 shell pipe

从交互式 go cli 中终止 shell pipe

Go
眼眸繁星 2022-08-01 10:53:21
我有一个Go程序,它使用来自shell管道的“实时”输入,例如:tail -f some/file | my-programmy-program是一个用 rivo/tview 构建的交互式程序。我希望能够使用Ctrl-C关闭我的程序,并让它也终止为其提供输入的。tail -f目前,我必须按Ctrl-C两次才能返回到我的shell提示符。我可以通过点击Ctrl-C一次回到我的提示吗?
查看完整描述

1 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

我们将假设一个类Unix系统,使用一个理解并参与工作控制的shell(他们现在都这样做了)。运行命令时,shell 会创建一个称为进程组或“pgroup”的东西来保存组成该命令的每个进程。如果命令是一个管道(就像这个一样),则管道中的每个进程都会获得相同的 pgroup-ID(请参阅 setpgid)。

如果命令在 forgeground 中运行(不带 ),则控制终端会分配此特定 pgid。按下其中一个信号生成键,例如或,使用内部 killpg 或等效项将相应的信号(在这些情况下)发送到 p 组。这会将信号发送到 p 组的每个成员。&CTRL-CCTRL-\SIGINTSIGQUIT

(后台处理进程只是*咳嗽*,收回控制tty上的pgid,然后重新启动管道中的进程。但是,实现这一目标并不是那么简单,正如此处的“重新启动”所示。

这里问题的可能根源是,交互式程序将控制终端置于cbreak原始模式,并禁用来自键盘键的部分或全部信号,例如,不再导致内核的tty模块发送信号。相反,如果您看到一个密钥应导致挂起 () 或终止,则程序必须执行自己的挂起或终止。程序员有时认为这包括简单地挂起或终止 - 但是由于整个管道从未获得有问题的信号,因此情况并非如此,除非整个shell管道仅由交互式程序组成。CTRL-CCTRL-Z

解决方法是让程序在对控制终端进行任何必要的清理(临时或永久)后将信号发送到自己的p组。


查看完整回答
反对 回复 2022-08-01
  • 1 回答
  • 0 关注
  • 118 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号