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つが巧妙になると、完全に予期しないコマンドが実行される可能性があります。ワンタイムスクリプトを書かない限り、それはひどいでしょう。
しなければならない
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
より良い方法はPythonを使用することです。
hashlib
ハッシュ値を計算します。
答え2
これは機能不足md5tool
ではなく、一般的なコマンドライン制限です。パラメータはスペースで区切ります。したがって、スペースを含むファイル名を渡すと、md5sum
各トークンは単一のファイルとして解釈されます。ファイル名を引用符で囲むことでこの問題を解決できます。つまり、行を変更してみてください。
cmd = 'md5sum' + ' ' + x
そして
cmd = 'md5sum' + ' "' + x + '"'
コマンドライン呼び出しは次のとおりです。
md5sum "file name with spaces.mp3"
したがって、md5sum
ハッシュは文句なしに計算されます。