2014-04-04 3 views
8

Ich benutze Open3 's popen3 Methode, um einen Prozess zu starten, der in einer konsoleähnlichen/REPL Art und Weise funktioniert, wiederholt Eingabe und Rückgabe zu akzeptieren.ruby ​​popen3 - Wie wiederhole ich auf stdin & lese stdout ohne re-opening process?

ich in der Lage bin, den Prozess zu öffnen, geben Sie senden und empfangen die Ausgabe ganz gut, mit Code wie folgt:

Open3.popen3("console_REPL_process") do |stdin, stdout, stderr, wait_thr| 
    stdin.puts "a string of input" 
    stdin.close_write 
    stdout.each_line { |line| puts line } #successfully prints all the output 
end 

Ich möchte in Folge, dass viele Male tun, ohne erneutes Öffnen der Prozess, da es eine lange Zeit dauert, um zu starten.

Ich weiß, dass ich stdin schließen muss, damit stdout zurückkommt .. aber was ich nicht weiß, ist, wie öffne ich 'stdin' so, dass ich mehr Eingabe schreiben kann?

Idealerweise möchte ich so etwas wie dies zu tun:

Open3.popen3("console_REPL_process") do |stdin, stdout, stderr, wait_thr| 
    stdin.puts "a string of input" 
    stdin.close_write 
    stdout.each_line { |line| puts line } 

    stdin.reopen_somehow() 

    stdin.puts "another string of input" 
    stdin.close_write 
    stdout.each_line { |line| puts line } 
    # etc.. 
end 

Lösung

Dank pmoo Antwort, ich war in der Lage, eine Lösung mit PTY und expect, erwarten die Prompt-String, dass der Prozess zu entwickeln, kehrt zurück, wenn es für mehr Eingabe bereit ist, wie folgt:

PTY.spawn("console_REPL_process") do |output, input| 
    output.expect("prompt >") do |result| 
     input.puts "string of input" 
    end 
    output.expect("prompt >") do |result| 
     puts result 
     input.puts "another string of input" 
    end 
    output.expect("prompt >") do |result| 
     puts result 
     input.puts "a third string of input" 
    end 
    # and so forth 
end 

Antwort

3

Sie können Erfolg mithabenBibliothek und hat das Kind Prozess explizit das Ende jeder Ausgabe markieren, wie:

require 'expect' 
require 'open3' 

Open3.popen3("/bin/bash") do 
    | input, output, error, wait_thr | 
    input.sync = true 
    output.sync = true 

    input.puts "ls /tmp" 
    input.puts "echo '----'" 
    puts output.expect("----", 5) 

    input.puts "cal apr 2014" 
    input.puts "echo '----'" 
    puts output.expect("----", 5) 
end 

Als Bonus expect hat eine timeout Option.

Verwandte Themen