我试图完成的任务是流化一个ruby文件并打印输出。(注意:我不想一次打印出所有内容)
main.py
from subprocess import Popen, PIPE, STDOUT
import pty
import os
file_path = '/Users/luciano/Desktop/ruby_sleep.rb'
command = ' '.join(["ruby", file_path])
master, slave = pty.openpty()
proc = Popen(command, bufsize=0, shell=True, stdout=slave, stderr=slave, close_fds=True)
stdout = os.fdopen(master, 'r', 0)
while proc.poll() is None:
data = stdout.readline()
if data != "":
print(data)
else:
break
print("This is never reached!")
红宝石睡眠.rb
puts "hello"
sleep 2
puts "goodbye!"
问题
流式传输文件工作正常。hello/goodbye输出以2秒延迟打印。完全符合剧本的要求。问题是readline()挂在最后,永远不会退出。我从来没找到最后的指纹。
我知道这里有很多像这样的问题,但是没有这些问题让我解决了这个问题。我对整个子流程不感兴趣,所以请给我一个更实际的回答。
问候
编辑
修复意外代码。(与实际错误无关)
不知道你的代码出了什么问题,但下面的代码似乎对我有用:
注意,我没有安装Ruby,因此无法检查您的实际问题。不过,在使用
ls
时效果很好。基本上,你在这里看到的是你的
proc.poll()
和readline()
之间的竞争条件。由于master
文件句柄上的输入从未关闭,因此,如果在ruby进程完成输出之后,进程试图对其执行readline()
操作,则永远不会有要读取的内容,但管道永远不会关闭。只有当shell进程在您的代码尝试另一个readline()之前关闭时,代码才能工作。以下是时间表:
简单的解决方法是只使用文档中建议的子流程模块,而不是与openpty结合使用:
http://docs.python.org/library/subprocess.html
这里有一个非常相似的问题需要进一步研究:
Using subprocess with select and pty hangs when capturing output
我假设您使用
pty
是由于Q: Why not just use a pipe (popen())?中列出的原因(到目前为止,所有其他答案都忽略了您的“注意:我不想一次打印所有内容”)。pty
仅限Linux as said in the docs:目前尚不清楚它在其他操作系统上的工作情况。
您可以尝试
pexpect
:或者^{} 在非交互模式下启用行缓冲:
或者基于@Antti Haapala's answer使用stdlib中的
pty
:这三个代码示例都会立即打印“hello”(只要看到第一个EOL)。
把旧的更复杂的代码示例留在这里,因为它可能会在其他文章中被引用和讨论
或者基于@Antti Haapala's answer使用
pty
:相关问题 更多 >
编程相关推荐