在 python 中控制 ruby 程序的标准输入和标准输出
Posted
技术标签:
【中文标题】在 python 中控制 ruby 程序的标准输入和标准输出【英文标题】:control stdin and stdout of a ruby program in python 【发布时间】: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编程等)
另外我认为不使用管道作为标准输出并使用类似文件的对象是一个更好的主意。 (如tempfile
或StringIO
等)
【问题讨论】:
【参考方案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))
【讨论】:
以上是关于在 python 中控制 ruby 程序的标准输入和标准输出的主要内容,如果未能解决你的问题,请参考以下文章
如何使用标准输入和标准输出在 C# 和 ruby 进程之间进行通信