Reputation: 1368
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
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