gpt4 book ai didi

python - 找到: missing argument to `-exec' when using subprocess

转载 作者:行者123 更新时间:2023-12-04 22:55:44 26 4
gpt4 key购买 nike

"find / -name 'testmkv-27311.mkv' -exec bash -c 'ffmpeg -i testmkv-27311.mkv -vcodec copy -acodec copy -codec:v libx264 -profile:v high -preset slow -b:v 500k -maxrate 500k -bufsize 1000k -vf scale=-1:480 -threads 0 -codec:a libfdk_aac -b:a 128k {}testmkv-27311.mp4' \;"

is the command i am passing and it gives error with find... there are some answers already about it but they are not making it clear... please help me execute this command...

最佳答案

直接问题:Shell 引用与 Python 引用

在 shell 中未引用的上下文中,\;防止;从被解析为命令分隔符。在没有 shell=True 的情况下从 Python 调用带有参数列表的命令时,但是,没有 shell 可以解释和删除该反斜杠,并且额外的引号使行为等同于传递 '\;'在 shell 中 -- 表示传递给 find 的参数不是确切的字符串 ;这是预期的,并且您会收到语法错误。

但是,原始代码在其他方面也是不正确的(以影响安全的方式!);应使用以下解决方案之一。

最小变化:使用 find安全地

就个人而言,如果您愿意在输出名称上稍微灵活一点(即 testmkv-27311.mkv.avi ),我会这样写:

subprocess.call([
'find', '/',
'-name', 'testmkv-27311.mkv',
'-exec',
'ffmpeg',
'-i', '{}',
'-vcodec', 'copy',
'-acodec', 'copy',
'-codec:v', 'libx264',
'-profile:v', 'high',
'-preset', 'slow',
'-b:v', '500k',
'-maxrate', '500k',
'-bufsize', '1000k',
'-vf', 'scale=-1:480',
'-threads', '0',
'-codec:a', 'libfdk_aac',
'-b:a', '128k',
'{}.mp4',
';',
])

尤其:
  • 我们是不是 调用外壳,从而避免外壳注入(inject)式安全漏洞。
  • 引用完全使用 Python 语法完成——不使用或不需要嵌套的 shell 引用。
  • POSIX 不需要 find -exec支持{}作为子字符串(而不是完整的参数)。因此,这个答案(就像问题中的代码一样)不像希望的那样可移植。


  • 替代方法: native Python 文件搜索

    也就是说,使用 find 并没有真正令人信服的理由。总之,当 Python 标准库可以为您进行搜索时,您可以轻松地自己更新名称:
    def convert(filename_in, filename_out):
    subprocess.call([
    'ffmpeg',
    '-i', filename_in,
    '-vcodec', 'copy',
    '-acodec', 'copy',
    '-codec:v', 'libx264',
    '-profile:v', 'high',
    '-preset', 'slow',
    '-b:v', '500k',
    '-maxrate', '500k',
    '-bufsize', '1000k',
    '-vf', 'scale=-1:480',
    '-threads', '0',
    '-codec:a', 'libfdk_aac',
    '-b:a', '128k',
    filename_out,
    ])

    target = 'testmkv-27311.mkv'
    for root, dir, files in os.walk('/'):
    if target in files:
    filename_in = os.path.join(dir, target)
    filename_out = filename_in[:-3]+'.mp4'
    convert(filename_in, filename_out)

    替代安全方法:硬编码脚本迭代参数

    作为另一种安全地执行此操作的方法( 不是 具有 find 修改或从名称生成代码,这允许这些名称被 shell 解析为代码),您可以让您的 bash 脚本迭代其论据:
    bash_script=r'''
    for filename; do
    ffmpeg -i "$filename" \
    -vcodec copy \
    -acodec copy \
    -codec:v libx264 \
    -profile:v high \
    -preset slow \
    -b:v 500k \
    -maxrate 500k \
    -bufsize 1000k \
    -vf scale=-1:480 \
    -threads 0 \
    -codec:a libfdk_aac \
    -b:a 128k \
    "${filename%.mkv}.mp4}"
    done
    '''

    subprocess.call([
    'find', '/',
    '-name', 'testmkv-27311.mkv',
    '-exec', 'bash', '-c', bash_script, '_',
    '{}', '+'])

    在这种情况下, _$0 的占位符在脚本中;后续参数( find 找到的文件名)在 $1 中传递, $2 , ETC;和 for filename; do (默认为 for filename in "$@"; do )将遍历它们。

    使用 -exec ... {} +将尽可能多的文件名传递给每个命令,而不是每个文件名调用一次命令;这减少了调用的 shell 的数量,从而提高了性能。

    关于python - 找到: missing argument to `-exec' when using subprocess,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45051547/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com