使用python子进程实时记录到文件

2024-09-30 02:35:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我想这真的很简单,但我做不出来。在

我正在尝试将DD映像子进程的输出实时写入日志文件—我使用DD v 8.25,从中可以使用写入stderr'status=progress'选项定期更新进度。在

我可以通过将file对象传递给stderr来让它实时记录完整的输出

log_file = open('mylog.log', 'a')
p = subprocess.Popen['dd command...'], stdout=None, stderr=log_file)

…但我更愿意先截取stderr中的字符串,以便在写入文件之前对其进行解析。在

我尝试过线程化,但似乎无法让它写入,或者,如果它写了,它只在进程结束时执行,而不是在进程期间。在

我是一个python noob,所以示例代码将不胜感激。谢谢!在

更新-正在工作(ISH)

我看了一下J.F.Sebastian建议的链接,找到了关于使用线程的帖子,所以在那之后我使用了“kill-USR1”技巧让DD将进度发布到stderr,然后我就可以拿起它:

^{pr2}$

唯一的问题是我不知道如何提高绩效。我只需要它每隔2秒左右报告一次状态,但是增加时间延迟会增加成像的时间,这是我不想要的。这是另一篇文章的问题。。。在

感谢塞巴斯蒂安和阿里。在


Tags: 文件对象log进程选项statusstderr记录
2条回答

在这个例子中,可以(使用python 3)从stderr流到控制台:

#! /usr/bin/env python
from subprocess import Popen, PIPE

# emulate a program that write on stderr
proc = Popen(["/usr/bin/yes 1>&2 "],  bufsize=512, stdout=PIPE, stderr=PIPE, shell=True)
r = b""
for line in proc.stderr:
    r += line
    print("current line", line, flush=True)

流式传输到文件:

^{pr2}$

要在终端中显示dd的进度报告并将输出保存(解析)到日志文件中:

#!/usr/bin/env python3
import io
from subprocess import PIPE, Popen
from time import monotonic as timer

cmd = "dd if=/dev/sda1 of=image.dd bs=524288 count=3000 status=progress".split()
with Popen(cmd, stderr=PIPE) as process, \
        open("log_file.log", "a") as log_file:
    start_time = timer()
    for line in io.TextIOWrapper(process.stderr, newline=''):
        print(line, flush=True, end='')  # no newline ('\n')
        if 'bytes' in line:
            # XXX parse line here, add flush=True if necessary
            print(line, file=log_file)
    # print duration
    print('Took {duration} seconds'.format(duration=timer() - start_time))

  • shell=True:这里不需要shell。Popen()可以直接运行dd
  • 没有线程,队列:这里不需要它们
  • 请不要使用while proc1.poll() == None您不需要它(如果proc1.poll()不是None,您将在proc1.stderr上看到EOF)。您可能会丢失数据(即使进程已经退出,也可能存在缓冲内容)。无关:如果需要与None进行比较,请使用is None而不是{}
  • io.TextIOWrapper(newline='')启用文本模式 (它使用locale.getpreferredencoding(False))并且 也将'\r'视为换行符
  • 使用默认值bufsize=-1(请参见^{}

相关问题 更多 >

    热门问题