md5sumにスペースを含むファイル名を理解させる。

md5sumにスペースを含むファイル名を理解させる。

md5sum複数の.mp3ファイルのチェックサムを計算するには、Pythonでパイプを使用する必要があります。プログラムコマンドラインでファイル名のスペースを無視するコマンドはありますか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. エスケープせずにシェルコマンドをアセンブルします。最悪の場合、ファイル名の1つが巧妙になると、完全に予期しないコマンドが実行される可能性があります。ワンタイムスクリプトを書かない限り、それはひどいでしょう。

  2. しなければならないos.popen()機能廃止Python 2.6から始めます。推奨される代替案は次のとおりです。subprocess.Popen()args前述のシェルエスケープの問題を回避するには、接続文字列の代わりにリストを引数として渡す必要があります。

    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. より良い方法はPythonを使用することです。hashlibハッシュ値を計算します。

答え2

これは機能不足md5toolではなく、一般的なコマンドライン制限です。パラメータはスペースで区切ります。したがって、スペースを含むファイル名を渡すと、md5sum各トークンは単一のファイルとして解釈されます。ファイル名を引用符で囲むことでこの問題を解決できます。つまり、行を変更してみてください。

cmd = 'md5sum' + ' ' + x

そして

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

コマンドライン呼び出しは次のとおりです。

md5sum "file name with spaces.mp3"

したがって、md5sumハッシュは文句なしに計算されます。

関連情報