使用 subprocess.PIPE 的 dd 和 md5sum 的动态输出

Dynamic output for dd & md5sum using subprocess.PIPE

我尝试组合 Link several Popen commands with pipes and Constantly print subprocess output while process is running 来动态捕获以下内容的输出:

sudo dd if=/dev/sdf bs=512 skip=10 count=1000000 status=progress | md5sum

在终端中这工作得很好。在 python3 中,我尝试使用子流程,建议使用 Replacing Shell Pipeline 方法将 | md5sum 部分链接到 CMD。这是我的代码到目前为止的样子: from subprocess import Popen, communicate, PIPE

dev = "/dev/sdf"
MD5_CMD = "sudo dd if={} bs=512 skip=10 count=1000000 status=progress | md5sum".format(dev)
tmp = Popen(MD5_CMD.split(), stderr=PIPE, stdout=PIPE, universal_newlines=True) 
process = Popen("md5sum", stdin=tmp.stdout, stdout=PIPE, stderr=PIPE, universal_newlines=True)
for line in iter(process.stdout.readline, ""):
    print(line)

但是我未能创建一个动态过程 - 我总是得到一个值:

>> d41d8cd98f00b204e9800998ecf8427e  -

我可以看到 ps -a 没有 md5sum 进程启动并且 运行。我也尝试使用 for l in process.communicate(): print(l) 但得到了相同的结果 - 因此我的方法在系统上是错误的。有人可以向我解释为什么带有 Popen 的命令 "stops" 不会在普通终端中停止吗?

我通过在命令中添加 catpv 解决了这个问题(pv - 一个可以查看管道的程序 - apt-get install pv):

CMD = "start=10; length=$((1000000 )); "  ## skip & count in the dd
CMD += "cat /dev/sda | dd bs=512 skip="$start" "
CMD += "count="$length" | pv -fs 1000M | md5sum"

process = Popen(["bash", "-c", CMD], stdout=PIPE, stderr=PIPE, text=True)

while True:
    line = process.stderr.readline()
    if not line:
        break
    lastline = line.strip()
    STATUS.update(lastline)

这会动态打印 md5sum 操作的输出。