Python сохраняет выходные данные для итерации и подпроцесса для контрольной суммы
Цель этого сценария - извлечь контрольную сумму md5 из каждого файла каталога в качестве источника, а затем (я также работаю над этим) выполнить сценарий в месте назначения, чтобы проверить правильность его копирования.
#!/usr/bin/env python
import os
from sys import *
import subprocess
script, path = argv
destination = "./new_directorio/"
archivo = "cksum.txt"
def checa_sum(x):
ck = "md5 %s" % x
p = subprocess.Popen(ck, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
out = open(archivo,'w')
out.write("%s" % (output))
out.close()
files = [f for f in os.listdir(path) if os.path.isfile(f)]
for i in files:
if not "~" in i:
checa_sum(i)
Что дает мне это файл с именем: "cksum.txt", но только один результат внутри файла.
bash-3.2$ more cksum.txt
MD5 (victor) = 4703ee63236a6975abab75664759dc29
bash-3.2$
Другая попытка вместо структуры "open", "write", "close" использует следующее:
def checa_sum(x):
ck = "md5 %s" % x
p = subprocess.Popen(ck, stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
with open(archivo,'w') as outfile:
outfile.write(output)
Почему мне выпадает только один результат, если я ожидаю следующий результат в файле?:
MD5 (pysysinfo.py) = 61a532c898e6f461ef029cee9d1b63dd
MD5 (pysysinfo_func.py) = ac7a1c1c43b2c5e20ceced5ffdecee86
MD5 (pysysinfo_new.py) = 38b06bac21af3d08662d00fd30f6c329
MD5 (test) = b2b0c958ece30c119bd99837720ffde1
MD5 (test_2.py) = 694fb14d86c573fabda678b9d770e51a
MD5 (uno.txt) = 466c9f9d6a879873688b000f7cbe758d
MD5 (victor) = 4703ee63236a6975abab75664759dc29
Более того, я не знаю, как решить пространство между каждой итерацией. Я тоже это ищу.
Получив это, я собираюсь сравнить каждый элемент, чтобы убедиться в его целостности после копирования в пункт назначения.
2 ответа
Ах, кто-то просил альтернативы, конечно есть:)
import logging
import hashlib
import os
outfile = "hash.log"
indir = "/Users/daniel/Sites/work"
logging.basicConfig(filename=outfile, filemode="w", format='%(message)s', level=logging.DEBUG)
for filename in (file for file in os.listdir(indir) if os.path.isfile(file) and not file.endswith("~")):
with open(filename) as checkfile:
logging.info(hashlib.md5(checkfile.read()).hexdigest())
Я использовал что-то подобное раньше.
что мне нравится, так это использование модуля журналирования, потому что он делает вещи масштабируемыми, мне не нужно держать файл открытым или продолжать его открывать. регистратор легко настраивается, но для генерации чего-то подобного, необходимого здесь, простая настройка - это одна строка.
здесь я не делаю парсинга консоли, потому что я использую hashlib pythons для генерации файла md5. Теперь можно сказать, что это может замедлить процесс, но, по крайней мере, с размерами файлов, с которыми я обычно сталкиваюсь, у меня до сих пор не было проблем.
Было бы интересно протестировать большие файлы, иначе механизм регистрации может также использоваться в вашем случае. я тогда предпочитал hashlib, потому что мне не нравился парсинг консоли.
Вы продолжаете открывать с w
и перезаписать, открыть с a
добавить.
Лучший способ - просто перенаправить стандартный вывод в файловый объект, например:
def checa_sum(x):
with open(archivo,'a') as outfile:
check_call(["md5",x], stdout=outfile)
с помощью check_call
поднимет CalledProcessError
для ненулевого статуса выхода, который вы должны обрабатывать соответственно.
Чтобы поймать исключение:
try:
check_call(["md5sum", x], stdout=outfile)
except CalledProcessError as e:
print("Exception for {}".format(e.cmd))
Используйте выражение генератора, чтобы получить файлы, и если вы хотите игнорировать копии, используйте not f.endswith("~")
:
files = (f for f in os.listdir("/home/padraic") if os.path.isfile(f) and not f.endswith("~"))
for i in files:
checa_sum(i)