pha*_*t0m 7 python iostream subprocess stdout stderr
我想捕获并显示我通过Python的子进程调用的进程的输出.
我以为我可以将我的文件类对象作为命名参数stdout和stderr传递
我可以看到它访问fileno属性 - 所以它正在对对象做一些事情.但是,write()永远不会调用该方法.我的方法是完全关闭还是我错过了什么?
class Process(object):
class StreamWrapper(object):
def __init__(self, stream):
self._stream = stream
self._buffer = []
def _print(self, msg):
print repr(self), msg
def __getattr__(self, name):
if not name in ['fileno']:
self._print("# Redirecting: %s" % name)
return getattr(self._stream, name)
def write(self, data):
print "###########"
self._buffer.append(data)
self._stream.write(data)
self._stream.flush()
def getBuffer(self):
return self._buffer[:]
def __init__(self, *args, **kwargs):
print ">> Running `%s`" % " ".join(args[0])
self._stdout = self.StreamWrapper(sys.stdout)
self._stderr = self.StreamWrapper(sys.stderr)
kwargs.setdefault('stdout', self._stdout)
kwargs.setdefault('stderr', self._stderr)
self._process = subprocess.Popen(*args, **kwargs)
self._process.communicate()
Run Code Online (Sandbox Code Playgroud)
我想要工作的东西是ANSI控制字符来移动光标并覆盖以前输出的东西.我不知道这是否是正确的术语,但这里是我的意思的一个例子:我正在尝试自动化一些GIT的东西,并且他们有自己更新的进度,而不是每次都写入新的行.
对我来说很重要的是,子进程的输出会立即显示出来.我已经尝试使用subprocess.PIPE捕获输出,并手动显示它,但我只能在进程完成后才能显示输出.但是,我想实时看到输出.
Sve*_*ach 12
进程的Stdin,stdout和stderr需要是真正的文件描述符.(这实际上不是Python强加的限制,而是管道在操作系统级别上的工作方式.)因此,您需要一个不同的解决方案.
如果你想同时跟踪stdout的stderr实时,你需要异步I/O或线程.
异步I/O:使用标准同步(=阻塞)I/O,对其中一个流的读取可能会阻塞,不允许实时访问另一个流.如果你是在Unix上,你可以在描述使用非阻塞I/O 这样的回答.但是,在Windows上,你会对这种方法感到不快.有关Python中异步I/O的更多信息,本视频中显示了一些替代方案.
线程:处理此问题的另一种常见方法是为要实时读取的每个文件描述符创建一个线程.线程只处理它们所指向的文件描述符,因此阻塞I/O不会造成损害.
| 归档时间: |
|
| 查看次数: |
5541 次 |
| 最近记录: |