开发者

How to proxy a shell process in ruby

I'm creating a script to wrap jdb (java debugger). I essentially want to wrap this process and proxy the user interaction. So I want it to:

  • start jdb from my script
  • send the output of jdb to stdout
  • pause and wait for input when jdb does
  • when the user enters commands, pass it to jdb

At the moment I really want a pass thru to jd开发者_运维技巧b. The reason for this is to initialize the process with specific parameters and potentially add more commands in the future.

Update: Here's the shell of what ended up working for me using expect:

PTY.spawn("jdb -attach 1234") do |read,write,pid|
  write.sync = true

  while (true) do
    read.expect(/\r\r\n> /) do |s|
      s = s[0].split(/\r\r\n/)
      s.pop # get rid of prompt                                                                                              

      s.each { |line| puts line }

      print '> '
      STDOUT.flush

      write.print(STDIN.gets)
    end
  end
end


Use Open3.popen3(). e.g.:

 Open3.popen3("jdb args") { |stdin, stdout, stderr|
     # stdin = jdb's input stream
     # stdout = jdb's output stream
     # stderr = jdb's stderr stream
     threads = []
     threads << Thread.new(stderr) do |terr|
         while (line = terr.gets)
            puts "stderr: #{line}"
         end
     end
     threads << Thread.new(stdout) do |terr|
         while (line = terr.gets)
            puts "stdout: #{line}"
         end
     end
     stdin.puts "blah"
     threads.each{|t| t.join()} #in order to cleanup when you're done.
 }

I've given you examples for threads, but you of course want to be responsive to what jdb is doing. The above is merely a skeleton for how you open the process and handle communication with it.


The Ruby standard library includes expect, which is designed for just this type of problem. See the documentation for more information.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜