猿问

从交互式 go cli 中终止 shell pipe

我有一个Go程序,它使用来自shell管道的“实时”输入,例如:

tail -f some/file | my-program

my-program是一个用 rivo/tview 构建的交互式程序。我希望能够使用Ctrl-C关闭我的程序,并让它也终止为其提供输入的。tail -f

目前,我必须按Ctrl-C两次才能返回到我的shell提示符。我可以通过点击Ctrl-C一次回到我的提示吗?


眼眸繁星
浏览 119回答 1
1回答

温温酱

我们将假设一个类Unix系统,使用一个理解并参与工作控制的shell(他们现在都这样做了)。运行命令时,shell 会创建一个称为进程组或“pgroup”的东西来保存组成该命令的每个进程。如果命令是一个管道(就像这个一样),则管道中的每个进程都会获得相同的 pgroup-ID(请参阅 setpgid)。如果命令在 forgeground 中运行(不带 ),则控制终端会分配此特定 pgid。按下其中一个信号生成键,例如或,使用内部 killpg 或等效项将相应的信号(在这些情况下)发送到 p 组。这会将信号发送到 p 组的每个成员。&CTRL-CCTRL-\SIGINTSIGQUIT(后台处理进程只是*咳嗽*,收回控制tty上的pgid,然后重新启动管道中的进程。但是,实现这一目标并不是那么简单,正如此处的“重新启动”所示。这里问题的可能根源是,交互式程序将控制终端置于cbreak或原始模式,并禁用来自键盘键的部分或全部信号,例如,不再导致内核的tty模块发送信号。相反,如果您看到一个密钥应导致挂起 () 或终止,则程序必须执行自己的挂起或终止。程序员有时认为这包括简单地挂起或终止 - 但是由于整个管道从未获得有问题的信号,因此情况并非如此,除非整个shell管道仅由交互式程序组成。CTRL-CCTRL-Z解决方法是让程序在对控制终端进行任何必要的清理(临时或永久)后将信号发送到自己的p组。
随时随地看视频慕课网APP

相关分类

Go
我要回答