在python中控制一个ruby程序的stdin和stdout

时间:2014-09-27 06:25:08

标签: python ruby python-2.7 python-3.x six-python

首先我应该注意:我是一名不懂红宝石的python程序员!

现在,我需要提供ruby程序的stdin并捕获脚本的stdout 一个python程序。
我试过this(第四个解决方案),代码在python2.7中工作,但在python3中没有; python3代码读取没有输出的输入。

现在,我需要一种方法将ruby程序绑定到python 2或3。

我的尝试:

此代码用六个模块编写,具有交叉版本兼容性。

  • python代码:

    from subprocess import Popen, PIPE as pipe, STDOUT as out
    
    import six
    
    print('launching slave')
    slave = Popen(['ruby', 'slave.rb'], stdin=pipe, stdout=pipe, stderr=out)
    
    while True:
        if six.PY3:
            from sys import stderr
            line = input('enter command: ') + '\n'
            line = line.encode('ascii')
        else:
            line = raw_input('entercommand: ') + '\n'
        slave.stdin.write(line)
        res = []
        while True:
            if slave.poll() is not None:
                print('slave rerminated')
                exit()
            line = slave.stdout.readline().decode().rstrip()
            print('line:', line)
            if line == '[exit]': break
            res.append(line)
        print('results:')
        print('\n'.join(res))
    
  • ruby​​代码:

    while cmd = STDIN.gets
        cmd.chop!
        if cmd == "exit"
            break
        else
            print eval(cmd), "\n"
            print "[exit]\n"
            STDOUT.flush
        end
    end
    

注意:

欢迎另外一种做这件事的方法! (如插座编程等)
另外我认为不使用pipe作为标准输出并使用类似文件的对象更好。 (例如tempfileStringIO等)

2 个答案:

答案 0 :(得分:1)

这是因为bufsize。在Python 2.x中,默认值为0(未加密)。在Python 3.x中,它更改为-1(使用系统的默认缓冲区大小)。

明确指定它可以解决您的问题。

slave = Popen(['ruby', 'slave.rb'], stdin=pipe, stdout=pipe, stderr=out, bufsize=0)

DEMO

答案 1 :(得分:0)

以下是关于我如何使用 Ruby 和 Python3 使其工作的代码。

红宝石奴隶

# read command from standard input:
while cmd = STDIN.gets
  # remove whitespaces:
  cmd.chop!
  # if command is "exit", terminate:
  if cmd == "exit"
    break
  else
    # else evaluate command, send result to standard output:
    print eval(cmd), "\n"
    print "[exit]\n"
    # flush stdout to avoid buffering issues:
    STDOUT.flush
  end
end

Python 大师

from subprocess import Popen, PIPE as pipe, STDOUT as out

print('Launching slave')
slave = Popen(['ruby', 'slave.rb'], stdin=pipe, stdout=pipe, stderr=out, bufsize=0)

while True:
    from sys import stderr
    line = input('Enter command: ') + '\n'
    line = line.encode('ascii')
    slave.stdin.write(line)
    res = []
    while True:
        if slave.poll() is not None:
            print('Slave terminated')
            exit()
        line = slave.stdout.readline().decode().rstrip()
        if line == '[exit]': break
        res.append(line)
    print('results:')
    print('\n'.join(res))