【问题标题】:Using a glob to generate arguments with subprocess.run()使用 glob 通过 subprocess.run() 生成参数
【发布时间】:2018-10-28 07:18:19
【问题描述】:

我想在 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

【问题讨论】:

  • 这是另一个副本。看在上帝的份上,开始关闭重复并停止回答重复,直到奶牛回家……它只会污染 SO。

标签: python python-3.x shell subprocess


【解决方案1】:

除非您指定shell=True(并且作为第一个近似值,您永远不应指定shell=True),您提供的参数将按原样传递,没有外壳扩展、分词或取消引号。因此,您作为参数传递的文件名正是/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

【讨论】:

    【解决方案2】:

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

    Globbing 无法按您预期的方式工作,您需要指定 shell=True,但随后您需要删除列表。

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

    应该做的伎俩。

    【讨论】:

    • 使用 shell=True 将参数化/非常量内容折叠到 shell 脚本部分是一个非常、非常的坏主意(可以安全地使用 shell=True,但是仅当内容在添加到字符串之前用shlex.quote()/pipes.quote() 引用,或者从该字符串带外添加到参数列表中)。如果您从上传文件夹中获取文件名,并且有人创建了一个名为 $(rm -rf ~) 的艺术家,那么您刚刚度过了非常糟糕的一天。见docs.python.org/2/library/…中的大红色部分
    • (...还有更多创造性的名字是可能的
    • ...另外,这里的代码似乎没有引用flac_files,因此名称中的空格将被shell分成单独的单词——也就是说,它将查找一个名为/home/fricadelle/Artist 的文件,然后是一个名为- 的文件,然后是一个名为Album 的文件,然后尝试扩展glob (2008)/*.flac
    • @charles: 括号也会有问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多