我的python脚本使用子进程来调用另一个脚本,这会产生非常慢的输出(逐行)。我希望在整个过程结束时将输出逐行写入文件并将整个输出写为字符串。以下代码在“脚本”结束时将输出写入“文件”。
args = ("script")
file = open('output.txt', 'w')
subprocess.Popen(args,stdout=file)
甚至可能吗? Thanx,Chris
答案 0 :(得分:2)
您可以使用轮询与流程进行交互,以便您可以尝试逐行进行交互:
例如:
process = subprocess.Popen(["ls", "-lart"],
bufsize=-1, # fully buffered (default)
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=os.curdir,
env=os.environ)
my_stdout_file = open("stdout.txt", "w")
while True:
process.poll()
line = process.stdout.readline()
my_stdout_file.write(line)
eline = process.stderr.readline()
if line:
stdout_lines.append(line)
if eline:
stderr_lines.append(eline)
if (line == "" and eline == "" and
process.returncode != None):
break
答案 1 :(得分:1)
是的,有可能。这是我为测试工具编写的一个函数,用于对Python shell脚本进行单元测试。
def testrun(cmdline):
try:
cmdout, cmderr = "",""
cmdp = Popen(cmdline, shell=True,stdout=PIPE, stderr=PIPE)
cmdout,cmderr = cmdp.communicate()
retcode = cmdp.wait()
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
return (retcode,cmdout,cmderr)
except OSError, e:
return (e,cmdout,cmderr)
该函数返回一个元组,其中包含sys.exit()
发出的shell返回码,标准输出文本和标准错误输出文本。它们都是文本字符串,因此您需要在处理之前使用splitlines
将它们分成行。
如果您确实需要逐行与输出进行交互,那么最好使用pexpect而不是subprocess
模块。
答案 2 :(得分:1)
以为我会共享一个不使用.poll(),. wait()或.communicate()的解决方案。几点:
import codecs
,因为我的输出包括东亚UTF-8文字try:
捕获每一行以过滤掉损坏/无效的UTF-8文本'\x0a'
来强制使用Linux换行符。for line in iter(subproc.stderr.readline, ''):
代码:
import subprocess
import codecs
import os
kw = {
'bufsize': 0,
'executable': None,
'stdin': subprocess.PIPE,
'stdout': subprocess.PIPE,
'stderr': subprocess.PIPE,
'preexec_fn': None,
'close_fds': False,
'shell': False,
'cwd': None,
'env': None,
'universal_newlines': False,
'startupinfo': None,
'creationflags': 0,
}
args = ['ls', '-lart']
kw['cwd'] = os.path.expanduser('~')
logfile = os.path.expanduser('~/stdout.txt')
stdlog = []
try:
subproc = subprocess.Popen(args,**kw)
except:
print 'Error loading subprocess. Check arguments and kwargs'
exit()
log = codecs.open(logfile,'w','utf-8')
log.write(': Starting log for: \"%s\"\x0a'%(' '.join(args)))
for line in iter(subproc.stdout.readline, ''):
try:
stdlog.append(line.rstrip().decode('utf-8'))
log.write(stdout[-1]+'\x0a')
print stdout[-1]
except:
pass
log.flush()
log.close()
答案 3 :(得分:0)
对于我正在处理的编程语言,我遇到了同样的问题,最后这样做了:https://github.com/perimosocordiae/plumbum/blob/master/lib/stdlib.py#L21
不幸的是,它涉及一次从输出流中读取一个字符,累积该行直到找到换行符。但是它很有用,而且我不知道有任何其他方法可以获得相同的行为。