使用glob通过subprocess.run()

时间:2018-05-17 22:24:52

标签: python python-3.x shell subprocess

我想在python脚本中使用metaflac(https://linux.die.net/man/1/metaflac)命令。

from subprocess import run

flac_files = "/home/fricadelle/Artist - Album (2008)/*.flac"
run(['metaflac', '--add-replay-gain', flac_files])

我得到了

The FLAC file could not be opened.  Most likely the file does not exist

或不可读。

如果我将shell = True添加到运行函数中,我会得到:

ERROR: you must specify at least one FLAC file;
   metaflac cannot be used as a pipe

那我该怎么办?谢谢!

PS:当然命令在shell中运行良好:

metaflac --add-replay-gain /home/fricadelle/Artist\ -\ Album \(2008\)/*.flac

2 个答案:

答案 0 :(得分:2)

除非您指定shell=True(并且作为第一个近似值,您不应该指定shell=True),否则您提供的参数将按原样传递,不进行shell扩展,分词或取消引用。因此,您作为参数传递的文件名正好是/home/fricadelle/Artist - Album (2008)/*.flac,这不是任何文件的名称。 (这就是为什么你不需要在空格和括号之前添加反斜杠。如果你指定shell=True - 我重复一遍,你真的应该避免 - 然后你需要包含反斜杠,这样shell就不会不要把名字分成几个不同的词。)

当您在shell中键入 flac_files = "/home/fricadelle/Artist - Album (2008)/*.flac未引用时,shell将尝试将其扩展为名称与模式匹配的所有文件的列表,然后将该列表作为单独的参数传递。由于subprocess.run不执行此操作,因此您必须自己执行此操作,通常使用glob.glob执行此操作。例如,

from subprocess import run
from glob import glob
flac_files = "/home/fricadelle/Artist - Album (2008)/*.flac"
run(['metaflac', '--add-replay-gain'] + glob(flac_files))

注意:与shell不同,如果模式与没有文件匹配,glob.glob将返回一个空列表。你真的应该检查这个错误而不是调用没有文件名选项的metaflac

答案 1 :(得分:-1)

请参阅答案here以获得更好的解释。

Globbing并不像你期望的那样工作,你需要指定shell=True,但是你需要删除列表。

run('metaflac --add-replay-gain ' + flac_files, shell=True)

应该做的伎俩。