我正在运行一个脚本,通过使用执行许多可执行文件
subprocess.call(cmdArgs,stdout=outf, stderr=errf)
Run Code Online (Sandbox Code Playgroud)
when outf/ errf是None或文件描述符(stdout/的不同文件stderr).
有什么方法可以执行每个exe,以便将stdout和stderr一起写入文件和终端?
问题: 我有一个设计糟糕的Fortran程序(我无法更改它,我坚持使用它)从stdin和其他输入文件中获取文本输入,并将文本输出结果写入stdout和其他输出文件.输入和输出的大小非常大,我想避免写入硬盘驱动器(慢速操作).我编写了一个函数,迭代几个输入文件的行,我也有多个输出的解析器.我真的不知道程序是否首先读取所有输入然后开始输出,或者在读取输入时开始输出.
目标: 拥有一个为外部程序提供所需功能的函数,并在输出来自程序时解析输出,而无需将数据写入硬盘驱动器上的文本文件.
研究: 使用文件的天真方式是:
from subprocess import PIPE, Popen
def execute_simple(cmd, stdin_iter, stdout_parser, input_files, output_files):
for filename, file_iter in input_files.iteritems():
with open(filename ,'w') as f:
for line in file_iter:
f.write(line + '\n')
p_sub = Popen(
shlex.split(cmd),
stdin = PIPE,
stdout = open('stdout.txt', 'w'),
stderr = open('stderr.txt', 'w'),
bufsize=1
)
for line in stdin_iter:
p_sub.stdin.write(line + '\n')
p_sub.stdin.close()
p_sub.wait()
data = {}
for filename, parse_func in output_files.iteritems():
# The stdout.txt and stderr.txt is included here
with open(filename,'r') as f: …Run Code Online (Sandbox Code Playgroud) 我正在通过Python的子进程模块运行脚本.目前我使用:
p = subprocess.Popen('/path/to/script', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = p.communicate()
Run Code Online (Sandbox Code Playgroud)
然后我将结果打印到stdout.这很好,但由于脚本需要很长时间才能完成,我还希望从脚本到stdout的实时输出.我输出输出的原因是因为我想解析它.
也许在以太中有人可以帮我解决这个问题.(我在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) …Run Code Online (Sandbox Code Playgroud) 我想捕获并显示我通过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, …Run Code Online (Sandbox Code Playgroud) 我正在尝试同时处理stdout和stderr从subprocess.Popen通过捕获两者的调用处理,subprocess.PIPE但希望在输出时处理输出(例如在终端上打印它们)。
我见过的所有当前解决方案都将等待Popen调用完成以确保捕获所有stdout和stderr,以便可以对其进行处理。
这是一个带有混合输出的示例 Python 脚本,在实时(或尽可能实时)处理它时,我似乎无法复制订单:
$ cat mix_out.py
import sys
sys.stdout.write('this is an stdout line\n')
sys.stdout.write('this is an stdout line\n')
sys.stderr.write('this is an stderr line\n')
sys.stderr.write('this is an stderr line\n')
sys.stderr.write('this is an stderr line\n')
sys.stdout.write('this is an stdout line\n')
sys.stderr.write('this is an stderr line\n')
sys.stdout.write('this is an stdout line\n')
Run Code Online (Sandbox Code Playgroud)
一种似乎可行的方法是使用线程,因为这样读取将是异步的,并且可以按照subprocess产生输出的方式进行处理。
这个只是处理stdoutfirst 和stderrlast的当前实现,如果输出最初在两者之间交替,这可能是欺骗性的:
cmd = ['python', 'mix_out.py']
process = subprocess.Popen( …Run Code Online (Sandbox Code Playgroud) python ×6
subprocess ×5
stdout ×2
asynchronous ×1
io ×1
iostream ×1
legacy ×1
parent ×1
stderr ×1