也许在以太坊里有人可以帮助我。(我在SO上看到了许多与此类似的问题,但是没有一个解决标准输出和标准错误的问题,也没有处理类似于我的情况的问题,因此是这个新问题。)
我有一个python函数,它将打开一个子进程,等待其完成,然后输出返回码,以及标准输出和标准错误管道的内容。在进程运行时,我还要在填充时显示两个管道的输出。我的第一次尝试导致了这样的事情:
process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout = str()
stderr = str()
returnCode = None
while True:
# collect return code and pipe info
stdoutPiece = process.stdout.read()
stdout = stdout + stdoutPiece
stderrPiece = process.stderr.read()
stderr = stderr + stderrPiece
returnCode = process.poll()
# check for the end of pipes and return code
if stdoutPiece == '' and stderrPiece == '' and returnCode != None:
return returnCode, stdout, stderr
if stdoutPiece != '': print(stdoutPiece)
if stderrPiece != '': print(stderrPiece)
但是有几个问题。因为read()
读取直到an EOF
,所以while
循环的第一行直到子进程关闭管道才返回。
我可以替换为read()
,read(int)
但是打印输出失真,在读取字符的末尾切断。我可以readline()
代替它,但是当同时发生很多输出和错误时,打印输出会因输出和错误的交替出现而失真。
也许有一个read-until-end-of-buffer()
我不知道的变体?还是可以实施?
也许最好按照另一个帖子的答案中的sys.stdout
建议实现一个包装器?但是,我只想在此函数中使用包装器。
社区还有其他想法吗?
感谢您的帮助!:)
编辑 :解决方案确实应该是跨平台的,但是如果您没有想法,请与他人分享以保持头脑风暴。
使用来使管道成为非阻塞状态fcntl.fcntl
,并使用select.select
来等待数据在任一管道中变为可用。例如:
# Helper function to add the O_NONBLOCK flag to a file descriptor
def make_async(fd):
fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
# Helper function to read some data from a file descriptor, ignoring EAGAIN errors
def read_async(fd):
try:
return fd.read()
except IOError, e:
if e.errno != errno.EAGAIN:
raise e
else:
return ''
process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
make_async(process.stdout)
make_async(process.stderr)
stdout = str()
stderr = str()
returnCode = None
while True:
# Wait for data to become available
select.select([process.stdout, process.stderr], [], [])
# Try reading some data from each
stdoutPiece = read_async(process.stdout)
stderrPiece = read_async(process.stderr)
if stdoutPiece:
print stdoutPiece,
if stderrPiece:
print stderrPiece,
stdout += stdoutPiece
stderr += stderrPiece
returnCode = process.poll()
if returnCode != None:
return (returnCode, stdout, stderr)
请注意,fcntl
仅在包括Cygwin的类Unix平台上可用。
如果您需要它在不使用Cygwin的Windows上运行,那是可行的,但难度要大得多。您必须:
SetNamedPipeHandleState
与withPIPE_NOWAIT
一起使用以使stdout和stderr管道不阻塞WaitForMultipleObjects
而不是select
等待数据可用ReadFile
读取数据问题内容: 我想捕获并显示通过Python的子流程调用的流程的输出。 我以为我可以将文件状对象作为参数stdout和stderr传递 我可以看到它访问了属性-因此它正在处理对象。但是,永远不会调用该方法。我的方法是否完全无效或我只是缺少什么? 更新: 我还想工作的是ANSI控制字符,用于移动光标并覆盖以前的输出内容。我不知道这是否是正确的术语,但这是我的意思的一个示例:我正在尝试使一些GIT自动化
问题内容: 我有一些脚本应该已经停止运行,但是永远挂在身边。我是否可以通过某种方式以一种可读的方式弄清楚它们正在向STDOUT和STDERR写入什么内容? 例如,我尝试执行以下操作: 但这确实不起作用。无论如何,这是一个远射。 还有其他想法吗? 就其本身而言,它很冗长且难以理解。 注意:我 只 对它们的输出感兴趣,而对其他任何东西都不感兴趣。我有能力自己弄清其他事情;这个问题只集中在获得访问std
问题内容: 我正在尝试修复这段代码,该代码是从具有车牌号和车主列表(该格式)的哈希图进行打印的。我试图通过printOwners()仅打印出所有者;但是我不能不打印重复的东西。 我已经玩了一段时间,但似乎无法跳过重复项。 这是我的代码: 问题答案: 要删除重复项,请使用: 或者使用Java 8 和方法:
此方法的输入为“9876548” 我不要结尾的“9876548”。 (叠加流格式不会全部 实现一个递归方法 printDigits,该方法将整数 num 作为参数,并以相反的顺序打印其数字,每行一个数字。 谢谢大家的帮助!
问题内容: 我有一个Python脚本正在使用我的雇主提供的某些封闭式Python函数(即我无法编辑这些函数)。当我调用这些函数时,它们会将输出打印到我想抑制的Linux终端上。我试过通过重定向标准输出/标准错误; 但这无法捕获输出。我认为我通过Python调用的函数(上面的rogue_function())实际上是经过编译的C代码的包装程序,它们实际上是在进行打印。 有谁知道一种方法可以对某个函数
问题内容: 我想通过python从目录中调用脚本(它们是可执行的shell脚本)。 到现在为止还挺好: 现在我想要的是:假设我有一个具有启动功能的bash脚本。我从那里打电话 回声“某事” 现在,我想看看sys.stdout和退出代码上的回显。我相信您可以使用.communicate()执行此操作,但是我的操作不符合我的预期。 我究竟做错了什么? 任何帮助深表感谢 问题答案: 授予http://d