Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在子进程运行时拦截其标准输出_Python_Process_Subprocess_Stdout_Popen - Fatal编程技术网

Python 在子进程运行时拦截其标准输出

Python 在子进程运行时拦截其标准输出,python,process,subprocess,stdout,popen,Python,Process,Subprocess,Stdout,Popen,如果这是我的子流程: import time, sys for i in range(200): sys.stdout.write( 'reading %i\n'%i ) time.sleep(.02) import subprocess, time, sys print 'starting' proc = subprocess.Popen( 'c:/test_apps/testcr.py', shell=True, stdin=subprocess

如果这是我的子流程:

import time, sys
for i in range(200):
    sys.stdout.write( 'reading %i\n'%i )
    time.sleep(.02)
import subprocess, time, sys

print 'starting'

proc = subprocess.Popen(
    'c:/test_apps/testcr.py',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE  )

print 'process created'

while True:
    #next_line = proc.communicate()[0]
    next_line = proc.stdout.readline()
    if next_line == '' and proc.poll() != None:
        break
    sys.stdout.write(next_line)
    sys.stdout.flush()

print 'done'
这是控制和修改子流程输出的脚本:

import time, sys
for i in range(200):
    sys.stdout.write( 'reading %i\n'%i )
    time.sleep(.02)
import subprocess, time, sys

print 'starting'

proc = subprocess.Popen(
    'c:/test_apps/testcr.py',
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE  )

print 'process created'

while True:
    #next_line = proc.communicate()[0]
    next_line = proc.stdout.readline()
    if next_line == '' and proc.poll() != None:
        break
    sys.stdout.write(next_line)
    sys.stdout.flush()

print 'done'
为什么
readline
communicate
要等待进程运行完毕?有没有一种简单的方法可以实时传递(和修改)子流程的stdout

顺便说一句,我已经看到了,但我不需要日志功能(而且我也没有费心去理解它)


我使用的是Windows XP。

进程输出已缓冲。在更多的UNIXy操作系统(或Cygwin)上,该模块可用,它背诵所有必要的咒语,以避免缓冲相关问题。但是,这些咒语需要一个工作模式,这在本机(非cygwin)win32 Python构建中是不可用的

在控制子流程的示例中,只要让它在必要时调用
sys.stdout.flush()
,但对于任意子流程,该选项不可用


另请参见pexpect常见问题解答。

进程输出已缓冲。在更多的UNIXy操作系统(或Cygwin)上,该模块可用,它背诵所有必要的咒语,以避免缓冲相关问题。但是,这些咒语需要一个工作模式,这在本机(非cygwin)win32 Python构建中是不可用的

在控制子流程的示例中,只要让它在必要时调用
sys.stdout.flush()
,但对于任意子流程,该选项不可用


另请参见pexpect常见问题解答。

正如Charles已经提到的,问题在于缓冲。我在为SNMPd编写一些模块时遇到了类似的问题,并通过用自动刷新版本替换stdout解决了这个问题

我使用了以下代码,灵感来自ActiveState上的一些帖子:

class FlushFile(object):
    """Write-only flushing wrapper for file-type objects."""
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

# Replace stdout with an automatically flushing version
sys.stdout = FlushFile(sys.__stdout__)

正如Charles已经提到的,问题在于缓冲。我在为SNMPd编写一些模块时遇到了类似的问题,并通过用自动刷新版本替换stdout解决了这个问题

我使用了以下代码,灵感来自ActiveState上的一些帖子:

class FlushFile(object):
    """Write-only flushing wrapper for file-type objects."""
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

# Replace stdout with an automatically flushing version
sys.stdout = FlushFile(sys.__stdout__)

我看不出这与在每个sys.stdout.readline()之后调用sys.stdout.flush()有什么不同,我就是这么做的。我还尝试为子流程设置bufsize=0。在子流程中需要刷新,而不是父流程。是的,在示例中,子流程也是一个python脚本。因此,替换子流程中的标准输出。在父进程中调用sys.stdout.flush()不会执行任何操作。确定。我知道我在那里做了什么。当然,这个子进程只是一个示例。我真正的过程是一个巨大的编译FORTRAN,我无法访问它的源代码。在这种情况下,我只需要希望孩子没有缓冲输出?那么subprocess.Popen的bufsize做什么呢?据我所知,是应用程序代码决定了输出缓冲区的大小。我不认为您可以在外部执行任何操作,除非它是动态链接的,并且您预加载了一个库来替换系统调用。但这是一个巨大的漏洞,超出了这个问题的范围:)我不认为这与在每个sys.stdout.readline()之后调用sys.stdout.flush()有什么不同,我就是这么做的。我还尝试为子流程设置bufsize=0。在子流程中需要刷新,而不是父流程。是的,在示例中,子流程也是一个python脚本。因此,替换子流程中的标准输出。在父进程中调用sys.stdout.flush()不会执行任何操作。确定。我知道我在那里做了什么。当然,这个子进程只是一个示例。我真正的过程是一个巨大的编译FORTRAN,我无法访问它的源代码。在这种情况下,我只需要希望孩子没有缓冲输出?那么subprocess.Popen的bufsize做什么呢?据我所知,是应用程序代码决定了输出缓冲区的大小。我不认为您可以在外部执行任何操作,除非它是动态链接的,并且您预加载了一个库来替换系统调用。但这是一个巨大的黑客行为,超出了这个问题的范围:)相关的:相关的: