gpt4 book ai didi

python - 将子进程的标准输出/标准错误重定向到文件

转载 作者:太空宇宙 更新时间:2023-11-03 12:07:34 24 4
gpt4 key购买 nike

我有一个 Python 脚本 (popen.py),它运行另一个 Python 脚本 (counter.py) 作为子进程,输出重定向到 /tmp/counter.log。我使用的代码是:

/tmp/counter.py

#!/usr/bin/env python2
import time

i = 0
while True:
print i
i +=1
time.sleep(1)

/tmp/popen.py

#!/usr/bin/env python2
import subprocess

f = open("/tmp/counter.log", "a+")
p = subprocess.Popen("/tmp/counter.py", stdout=f, stderr=f, bufsize=1)

然而,当我运行 popen.py 时,子进程被创建并保持运行,但是在输出达到 4096 字节之前没有任何内容写入 /tmp/counter.log , 然后它似乎被刷新到文件中。

有什么方法可以让我的子进程在不修改 counter.py 脚本本身的情况下逐行写入日志文件?

我不想修改 counter.py 的原因是子进程可能并不总是运行 Python 脚本。我尝试过运行一个小型可执行文件(用 C 编写)的相同操作,但出现了同样的问题。

我已经尝试为该文件编写一个自刷新包装器并将其用于 stdout,如 here 所述但这也不起作用。

我已经使用 lsofstrace 进行了一些调试,这是我设法找出的结果:

lsof(文件描述符)

手动运行/tmp/counter.py

COMMAND PID   USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
python2 629 daniel 0u CHR 136,0 0t0 3 /dev/pts/0
python2 629 daniel 1u CHR 136,0 0t0 3 /dev/pts/0
python2 629 daniel 2u CHR 136,0 0t0 3 /dev/pts/0

通过/tmp/popen.py 运行/tmp/counter.py

COMMAND PID   USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
python2 638 daniel 0u CHR 136,0 0t0 3 /dev/pts/0
python2 638 daniel 1u REG 202,0 0 768 /tmp/counter.log
python2 638 daniel 2u REG 202,0 0 768 /tmp/counter.log

strace(while循环中的系统调用)

手动运行/tmp/counter.py

select(0, NULL, NULL, NULL, {1, 0})     = 0 (Timeout)
write(1, "11\n", 3) = 3
select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
write(1, "12\n", 3) = 3
select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
write(1, "13\n", 3) = 3
select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
write(1, "14\n", 3) = 3
select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
write(1, "15\n", 3) = 3

通过/tmp/popen.py 运行/tmp/counter.py

select(0, NULL, NULL, NULL, {1, 0})     = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)
...
write(1, "11\n12\n13\n14\n15\n16\n17\n18\n"..., 4096) = 4096

最佳答案

我最终使用的解决方案并没有完全解决问题,但在这一点上是最可接受的折衷方案,是在生成子进程时设置 PYTHONUNBUFFERED 环境变量:

#!/usr/bin/env python2
import subprocess

f = open("/tmp/counter.log", "a+")
p = subprocess.Popen("/tmp/counter.py", stdout=f, stderr=f, env={
"PYTHONUNBUFFERED": "Yes please"
})

这在额外代码和额外进程方面的开销最低,但仅当子进程是 Python 脚本时才有效。

关于python - 将子进程的标准输出/标准错误重定向到文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24686614/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com