2016-02-03 7 views
-1

Я строю программу в Ruby, которая должна читать в других программах 'stdout и отправить текст на их stdin. Текущее решение, которое я нашел, - это использование JRuby и использование некоторых знакомых функций Java для выполнения задачи. Есть ли для этого чисто рубиновое решение?Что такое рубиновый путь трубопровода?

require 'java' 

java_import java.lang.ProcessBuilder 
java_import java.io.PrintStream 
java_import java.util.Scanner 

process = ProcessBuilder.new("bc", "-i").start 
Thread.new { 
    input = Scanner.new(process.input_stream) 
    while input.has_next_line? do 
     puts("<- bc: " + input.next_line) 
    end 
} 
output = PrintStream.new(process.output_stream) 
loop do 
    s = gets.chomp 
    if s == "exit" 
     break 
    end 
    output.println(s) 
    output.flush 
end 

запустить программу

<- bc: bc 1.06.95 
<- bc: Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. 
<- bc: This is free software with ABSOLUTELY NO WARRANTY. 
<- bc: For details type `warranty'. 
1+1 
<- bc: 1+1 
<- bc: 2 
<- bc: 
2*3 
<- bc: 2*3 
<- bc: 6 
<- bc: 
exit 
+2

Есть несколько способов, но лучше всего подходит для задачи с любой сложности, вероятно, [open3] (http://ruby-doc.org/stdlib-2.3 .0/libdoc/open3/rdoc/Open3.html) из стандартной библиотеки. –

+0

Ruby имеет несколько способов открытия труб и отправки информации между запущенными скриптами или другими приложениями. Для этого есть много примеров и документации. Я бы предложил сделать больше исследований. –

+0

Существует почти точный пример, который у вас есть (с участием 'bc') в документации для [Open3 # popen2] (http://ruby-doc.org/stdlib-2.3.0/libdoc/open3/rdoc/Open3.html# метод-с-popen2) – Amadan

ответ

0

Если вы хотите читать выход из программы, то вам лучше всего, чтобы породить псевдо терминала (PTY), поэтому его выход строки в буфер. К счастью, это довольно легко с модулем PTY от Ruby. В примере я использую IO.select и неблокирующие вызовы, чтобы избежать потоков.

#!/usr/bin/env ruby 
require 'pty' 

r, w, pid = PTY.spawn('bc -i') 
running = true 

while running 
    fds = IO.select([$stdin, r]) 

    # fds[0] is an array of IO objects that are ready to be read from 
    fds[0].each do |fd| 
    if fd == r 
     output = r.read_nonblock(1024) 
     output.split("\n").each { |l| puts '<- bc: ' + l } 
    elsif fd == $stdin 
     line = $stdin.gets.strip 
     if line == 'exit' 
     running = false 
     break 
     end 

     w.write_nonblock(line + "\n") 
    end 
    end 
end 

Process.kill("TERM", pid) 
Process.waitpid(pid) 

выходы,

<- bc: bc 1.06.95 
<- bc: Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. 
<- bc: This is free software with ABSOLUTELY NO WARRANTY. 
<- bc: For details type `warranty'. 
<- bc: 
1+1 
<- bc: 1+1 
<- bc: 2 
2*3 
<- bc: 2*3 
<- bc: 6 
exit 
Смежные вопросы