59

我一直在尝试传递一个命令,该命令仅适用于命令行"concat:file1|file2"中 ffmpeg 参数周围的文字双引号。

但是,我不能使用subprocess.Popen(). 任何人都知道如何将引号传递给 subprocess.Popen?

这是代码:

command = "ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4"

output,error = subprocess.Popen(command, universal_newlines=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()

当我这样做时,ffmpeg 除了在 concat 段周围引用引号外,不会采取任何其他方式。有没有办法成功地将这一行传递给 subprocess.Popen 命令?

4

7 回答 7

63

我建议使用列表形式的调用而不是引用的字符串版本:

command = ["ffmpeg", "-i", "concat:1.ts|2.ts", "-vcodec", "copy",
           "-acodec", "copy", "temp.mp4"]
output,error  = subprocess.Popen(
                    command, universal_newlines=True,
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

这更准确地表示了将要传递给最终进程的确切参数集,并且无需弄乱 shell 引用。

也就是说,如果您绝对想使用纯字符串版本,只需使用不同的引号(和shell=True):

command = 'ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4'
output,error  = subprocess.Popen(
                    command, universal_newlines=True, shell=True,
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
于 2013-02-18T03:10:59.270 回答
9

使用单引号'around the "whole pattern"'自动转义双精度或显式"escape the \"double quotes\"". 您的问题与此无关Popen

只是为了记录,我遇到了一个问题,特别是在 Windows 下list传递给Popen它的基于 - 的命令不会在 glob 模式周围保留正确的双引号(即在接受的答案中建议的内容)。' '.join(cmd)在传递列表之前将列表加入字符串以Popen解决问题。

于 2016-08-23T08:45:01.903 回答
8

这适用于 python 2.7.3 自从旧版本的 python 以来,将 stderr 传输到 stdout 的命令已经改变:

把它放在一个名为 test.py 的文件中:

#!/usr/bin/python
import subprocess

command = 'php -r "echo gethostname();"'
p = subprocess.Popen(command, universal_newlines=True, shell=True, 
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
text = p.stdout.read()
retcode = p.wait()
print text

调用它:

python test.py

它打印我的主机名,即 apollo:

apollo

阅读 subprocess 手册:http: //docs.python.org/2/library/subprocess.html

于 2013-12-10T05:20:29.240 回答
2

我一直在处理类似的问题,通过 ssh 运行相对复杂的命令。它也有多个双引号和单引号。因为我正在通过 , 等管道python传输ssh命令powershell

如果您可以将命令转换为 shell 脚本,并通过 运行 shell 脚本subprocess.call/Popen/run,这些问题就会消失。

因此,根据您是在 Windows 上还是在 linux 或 mac 上,将以下内容放入 shell 脚本中 (script.shscript.bat)

ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4

然后你可以运行

import subprocess; subprocess.call(`./script.sh`; shell=True)

无需担心单引号等。

于 2018-03-17T22:20:27.653 回答
0

还在为包含空格的字符串参数而苦苦挣扎,并且不想使用shell=True

解决方案是对内部字符串使用双引号。

args = ['salt', '-G', 'environment:DEV', 'grains.setvals', '{"man_version": "man-dev-2.3"}']

try:
    p = subprocess.Popen(args, stdin=subprocess.PIPE
                             , stdout=subprocess.PIPE
                             , stderr=subprocess.PIPE
                        )
    (stdin,stderr) = p.communicate()
except (subprocess.CalledProcessError, OSError ) as err:
    exit(1)
if p.returncode != 0:
    print("Failure in returncode of command:")
于 2018-07-31T06:50:12.557 回答
0

任何遭受这种痛苦的人。它也适用于用引号括起来的参数。

params = ["ls", "-la"]
subprocess.check_output(" ".join(params), shell=True)
于 2022-01-08T23:42:39.950 回答
0

您问题中的这行代码不是有效的 Python 语法:

command = "ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4"

如果你有一个只有这一行的 Python 文件,你会得到一个语法错误。用双引号括起来的字符串文字中不能有双引号,除非它们用反斜杠转义。因此,您可以通过将其替换为以下内容来修复该行:

command = "ffmpeg -i \"concat:1.ts|2.ts\" -vcodec copy -acodec copy temp.mp4"

修复这一行的另一种方法是在 Python 中对字符串文字使用单引号,这样当字符串本身包含双引号时 Python 就不会混淆:

command = 'ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4'

修复语法错误后,您可以使用 using 解决该问题subprocess,如本答案中所述。我还写了这个答案来解释一个有用的心理模型subprocess

于 2022-01-11T15:06:09.510 回答