xtlc
xtlc

Reputation: 1368

Dynamic output for dd & md5sum using subprocess.PIPE

I tried combining Link several Popen commands with pipes and Constantly print subprocess output while process is running to dynamically catch the output of:

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

In the terminal this works just fine. In python3 I tried using subprocess and it's suggested Replacing Shell Pipeline method to chain the | md5sum part to the CMD. This is how my code looks so far: 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)

But I fail to create a dynamic process - I always get one value back:

>> d41d8cd98f00b204e9800998ecf8427e  -

and I can see with ps -a that no md5sum process is up and running. I also tried using for l in process.communicate(): print(l) but got the same result - therefore my approach is systematically wrong. Can someone please explain to me why the command "stops" with Popen and does not stop in the normal terminal?

Upvotes: 1

Views: 442

Answers (1)

xtlc
xtlc

Reputation: 1368

I solved this by adding cat and pv to the command (pv - a programm that can look into pipes - 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)

This dynamically prints the output of the md5sum operation.

Upvotes: 0

Related Questions