我想在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)
应该做这个伎俩。