【问题标题】:control stdin and stdout of a ruby program in python在 python 中控制 ruby​​ 程序的标准输入和标准输出
【发布时间】:2014-11-22 04:41:57
【问题描述】:

首先我应该注意到:我是一个 python 程序员,对 ruby​​ 一无所知!

现在,我需要输入一个 ruby​​ 程序的标准输入并使用以下命令捕获脚本的标准输出 一个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))
    
  • 红宝石代码:

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

注意:

欢迎使用其他方式来做这些事情! (如socket编程等)
另外我认为不使用管道作为标准输出并使用类似文件的对象是一个更好的主意。 (如tempfileStringIO 等)

【问题讨论】:

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


    【解决方案1】:

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

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

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

    DEMO

    【讨论】:

      【解决方案2】:

      下面是我如何使用 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))
      
      

      【讨论】:

        猜你喜欢
        • 2013-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-11
        • 1970-01-01
        • 2010-12-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多