在运行子命令时吞咽用户输入

我正在Ruby中编写一个简单的REPL( adb的命令行包装器),我支持两种命令:

  1. 交互式命令
  2. 非交互式命令

对于2,我只想从REPL调用系统命令,在输出文本时捕获其输出,并允许用户从该命令退回到REPL。 例:

 >> logcat ... // log output here ! user hits CTRL-D >> // back at the prompt 

这是在我的程序中发生的,而不是系统shell。

现在问题是:当logcat运行时,父进程(REPL)继续捕获键击,然后在命令退出时立即重放(?)它们。 这意味着,如果例如命中返回几次,然后按CTRL-C,它将退出子命令返回到REPL但重播所有键击,REPL不理解(如果其中一次击键发生要成为CTRL-D,它甚至会无意中退出我的程序……这显然不是我想要的。)

现在我尝试了多种不同的执行子命令的方法(通过反引号,系统,exec),我尝试flushrewind $stdin然后再回到循环中,我试图捕获CTRL-C中断,但没有任何作用。

我确信Ruby中必须有一种方法:

  1. 开始一个子过程
  2. 将所有用户输入路由到该进程并且仅将该进程路由(即不是父进程)
  3. 在CTRL-C上返回父进程

知道怎么做到这一点?

您可以尝试以下内容:

 Signal.trap("INT") {} # ignore sigint in the parent IO.popen "sort" do |io| # run sort in a sub process puts io.read # output stdout end Signal.trap("INT") { exit } # restore sigint while true do puts "looping" sleep 1 end 

如果您运行该程序,您可以输入:

 $ ruby test.rb c d b ^D b c d looping looping ^C $ 

要么

 $ ruby test.rb c d b ^C looping looping ^C $ 

它的工作原理是因为popen在子进程中运行命令,该进程有自己的信号处理。

Interesting Posts