Swallowing user input while running a sub-command

扶醉桌前 提交于 2019-12-07 13:11:12

问题


I'm writing a simple REPL (a command line wrapper for adb) in Ruby where I support two kinds of commands:

  1. interactive commands
  2. non-interactive commands

As for 2, I simply want to invoke a system command from the REPL, capture its output while it's outputting text, and allow the user to exit back into the REPL from that command. Example:

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

This is to happen within my program, not the system shell.

Now the problem is: while logcat is running, the parent process (the REPL) keeps capturing keystrokes and then replays (?) them as soon as the command exits. That means, if for instance hit return a few times, then CTRL-C, it will exit out of the sub command back into the REPL but replay all the keystrokes again, which the REPL doesn't understand (if one of those keystrokes happened to be CTRL-D, it will even unintentionally exit my program... this is obviously not what I want.)

Now I have tried multiple different ways of executing the sub command (via backtick, system, exec), I tried to flush and rewind $stdin before entering back into the loop, I tried trapping the CTRL-C interrupt, but nothing works.

I'm sure there must be a way in Ruby to:

  1. start a sub process
  2. route all user input to that process and only that process (i.e. not the parent process)
  3. return to parent process on CTRL-C

Any idea how to accomplish that?


回答1:


You can try something like the following:

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

If you run the program you can type in:

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

or

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

It works because popen runs the command in a sub process, which has its own signal handling.



来源:https://stackoverflow.com/questions/22426540/swallowing-user-input-while-running-a-sub-command

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!