【问题标题】:python saving output from a for iteration and subprocess for checksumpython保存迭代的输出和校验和的子进程
【发布时间】:2015-04-02 15:27:00
【问题描述】:

此脚本的目的是从目录的每个文件中提取 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$ 

另一个尝试,而不是“打开”,“写入”,“关闭”结构使用以下:

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

此外,我不知道如何处理每次迭代之间的空间。我也在找那个。

有了这个之后,我将比较每个项目以验证完整性一旦被复制到目的地。

【问题讨论】:

    标签: python for-loop subprocess md5


    【解决方案1】:

    啊,有人问了,当然有:)

    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())
    

    我以前一直在使用类似的东西。

    我喜欢使用 logging 模块,因为它使事情具有可扩展性,我不必保持文件打开或继续打开它。记录器是高度可配置的,但是为了在这里生成类似需要的东西,简单的设置就是一个衬里。

    这里我没有做任何控制台解析,因为我使用 pythons hashlib 来生成文件 md5.现在有人可以说,这样做可能会减慢速度,但至少对于我通常遇到的文件大小,到目前为止我没有任何问题。

    在较大的文件上进行测试会很有趣,否则日志记录机制也可以用于您的情况。那时我只喜欢 hashlib,因为我不喜欢解析控制台输出。

    【讨论】:

    • 我计划计算通常非常大的电影文件:有时每帧 1.5G(.ARI. R3D 文件),因此需要确保传输正常。让我实现你的代码,看起来很方便。
    • 我担心这么大的文件,你可能会从控制台解析 md5 运行得更快,但你仍然可以组合方法。我认为我拥有的最大文件约为 700 mb,但我现在已经在较小的文件上进行了测试
    • 顺便说一句。如果你想在服务器上运行相同的工作来比较文件,这是你“常规”做的事情,那么你应该检查一下结构:fabfile.org
    • 文件将在本地进行比较。但是,一旦它们在云中,作为参考就知道了。谢谢!让我将我的代码返回给你们,以进行一些改进。
    【解决方案2】:

    你一直用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)
    

    【讨论】:

    • 哦,谢谢。基本上做到了。谢谢!非常欢迎任何其他改进。
    • @x1c70r,除了可能使用生成器表达式而不是 os.listdir 调用的列表之外,一切看起来都很好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多