使 md5sum 理解带空格的文件名

使 md5sum 理解带空格的文件名

我需要md5sum在Python中使用管道来计算一堆.mp3文件的校验和...是否有一个命令可以忽略程序命令行上文件名中的空格md5sum

例如:

import os
def index(directory):
    stack = [directory]
    files = []
    while stack:
        directory = stack.pop()
        for file in os.listdir(directory):
            fullname = os.path.join(directory, file)
            if fullname.endswith('mp3'):
                files.append(fullname)
            if os.path.isdir(fullname) and not os.path.islink(fullname):
                stack.append(fullname)
    return files

def check(directory):
    files = index(directory)
    hvalues = []
    for x in files:
        cmd = 'md5sum' + ' ' + x
        fp = os.popen(cmd)
        res = fp.readline()
        hvalues.append(res)
        stat = fp.close() # What to do with stat?
    return hvalues

命令cmd = 'md5sum' + ' ' + x无法在包含空格或特殊字符的文件上正常工作,因为“md5sum”工具缺乏正确处理(散列)文件名中包含空格的文件的能力。

答案1

正如 @binfalse 指出的,问题不在于程序md5sum,而在于调用它的方式。您的代码实际上在几个层面上都很糟糕:

  1. 您无需转义就组装了一个 shell 命令。在最坏的情况下,如果其中一个文件名恰好是巧妙设计的,则可能会导致执行完全意想不到的命令。那将是可怕的,除非您正在编写一次性脚本。

  2. os.popen()函数已已弃用从 Python 2.6 开始。推荐的替代品是subprocess.Popen()。请务必传递一个列表作为args参数,而不是连接字符串,以避免前面提到的 shell 转义问题。

    def check(directory):
        files = index(directory)
        hvalues = []
        for f in files:
            cmd = ['md5sum', f]
            proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
            hvalues.append(proc.stdout.readline())
            proc.stdout.close()
            stat = os.waitpid(proc.pid, 0)
        return hvalues
    
  3. 更好的是,使用 Pythonhashlib计算哈希值。

答案2

这并不是缺乏能力,md5tool而是一般的命令行限制。参数之间用空格分隔。因此,如果您传递包含空格的文件名,md5sum它将把每个标记解释为单个文件。您可以通过用引号将文件名括起来来解决这个问题。也就是说,尝试更换线路

cmd = 'md5sum' + ' ' + x

cmd = 'md5sum' + ' "' + x + '"'

你的命令行调用看起来像

md5sum "file name with spaces.mp3"

因此,md5sum将计算哈希而不会抱怨。

相关内容