使用 glob 通过 subprocess.run() 生成参数



我想在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:当然,该命令在外壳中工作正常:

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

除非你指定shell=True(作为第一个近似值,你永远不应该指定shell=True),否则你提供的参数将按原样传递,没有外壳扩展、分词或引用。因此,您作为参数传递的文件名正好是/home/fricadelle/Artist - Album (2008)/*.flac,这不是任何文件的名称。(这就是为什么您不需要在空格和括号之前添加反斜杠的原因。如果你指定了shell=True- 我再说一遍,你真的应该避免这种情况 - 那么你需要包含反斜杠,这样shell就不会将名称拆分成几个不同的单词。

当您在 shell 中键入不带引号 flac_files = "/home/fricadelle/Artist - Album (2008)/*.flac时,shell 将尝试将其扩展为名称与 then 模式匹配的所有文件的列表,然后将该列表作为单独的参数传递。由于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

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

通配不像你期望的那样工作,你需要指定shell=True,但随后你需要删除列表。

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

应该做这个伎俩。

最新更新