我正在Ruby中编写一个简单的REPL(adb
的命令行包装器),我支持两种命令:
对于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),我尝试flush
和rewind
$stdin
然后再回到循环中,我试图捕获CTRL-C中断,但没有任何作用。
我确信Ruby必须有办法:
知道如何实现这个目标吗?
答案 0 :(得分:1)
您可以尝试以下内容:
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在子进程中运行命令,该进程有自己的信号处理。