追加子进程。Popen 输出到文件?

问题描述 投票:0回答:4

我可以成功地将输出重定向到文件,但这似乎会覆盖文件的现有数据:

import subprocess
outfile = open('test','w') #same with "w" or "a" as opening mode
outfile.write('Hello')
subprocess.Popen('ls',stdout=outfile)

将从文件中删除

'Hello'
行。

我想一个解决方法是将输出存储在其他地方作为字符串或其他东西(它不会太长),并用

outfile.write(thestring)
手动附加它 - 但我想知道我是否在模块中遗漏了有助于此的某些内容.

python subprocess popen
4个回答
37
投票

您当然可以将

subprocess.Popen
的输出附加到文件中,我每天都会使用它。我是这样做的:

log = open('some file.txt', 'a')  # so that data written to it will be appended
c = subprocess.Popen(['dir', '/p'], stdout=log, stderr=log, shell=True)

(当然,这是一个虚拟示例,我没有使用

subprocess
来列出文件...)

顺便说一句,其他行为类似于文件的对象(特别是

write()
方法)可以替换这个
log
项,这样你就可以缓冲输出,并用它做任何你想做的事情(写入文件、显示等) [但这似乎并不那么容易,请参阅下面我的评论]。

注意:可能会产生误导的是,由于某种我不明白的原因,

subprocess
会写在之前你想写的内容。所以,这是使用它的方法:

log = open('some file.txt', 'a')
log.write('some text, as header of the file\n')
log.flush()  # <-- here's something not to forget!
c = subprocess.Popen(['dir', '/p'], stdout=log, stderr=log, shell=True)

所以提示是:不要忘记

flush
输出!


2
投票

问题是,如果您希望标头成为标头,那么您需要在其余输出写入文件之前刷新:D


1
投票

我遇到了同样的问题并使用以下代码解决了它:

with open("outfile.log", 'w') as f:  # use 'a' if you need to append
    subprocess.Popen(['ls', '-la'], shell=False,
                     stdout=f.fileno(),
                     stderr=f.fileno())

0
投票

文件中的数据真的被覆盖了吗?在我的 Linux 主机上,我有以下行为: 1)在单独的目录中执行代码会得到:

$ cat test
test
test.py
test.py~
Hello

2)如果我在

outfile.flush()
之后添加
outfile.write('Hello')
,结果会略有不同:

$ cat test
Hello
test
test.py
test.py~

但是输出文件在这两种情况下都有

Hello
。如果没有显式的
flush()
调用,当 python 进程终止时,stdout 缓冲区将被刷新。 问题出在哪里?

© www.soinside.com 2019 - 2024. All rights reserved.