我正在寻找一种方法,可以将包含双引号的参数传递给Python的subprocess模块,而不需要对双引号进行转义。我看到过类似的问题被问了几次,当引号围绕着参数时,答案通常是删除引号。但我遇到的问题是,引号是参数的一部分,必须将其传递给脚本,而不能在每个引号前面添加反斜杠。例如:我正在调用subprocesTest.bat,一个简单的批处理脚本,它接受一个参数并将其回显:
echo "%~1"
我用一个包含引号的参数从Python调用批处理脚本:
import subprocess
test_string = 'Bill said "Hi!"'
cmd = ["subprocesTest.bat",
test_string
]
p = subprocess.Popen(cmd)
p.wait()
期望输出:
"Bill 说:\"嗨!\""
实际输出:
"Bill 说:\"Hi!\""
当我从命令行调用相同的批处理脚本时,可以得到期望的输出:
subprocesTest.bat "Bill 说:\"嗨!\""
查看源代码,subprocess.py中的list2cmdline函数已有文档说明:
3) A double quotation mark preceded by a backslash is
interpreted as a literal double quotation mark.
然而,如果我逐步执行此函数,我发现没有办法通过不在双引号前加反斜杠的方式传递双引号:
elif c == '"':
# Double backslashes.
result.append('\\' * len(bs_buf)*2)
bs_buf = []
result.append('\\"')
所以我有两个问题...
- 如果不添加反斜杠,是否可以向subprocess传递包含双引号的参数?
- 如果不可能,有人能解释一下为什么设计函数是这样的吗?函数文档字符串中的第三项似乎表明我可以通过添加反斜杠来传递一个文字引用,但这并没有产生我想要的行为。我读错文档了吗?
以下是其他讨论此问题的线程,并通过不使用引号进行绕过:
我没有看到对我实际想要传递引号的情况的回应。
Popen('subprocesTest.bat "Bill said "Hi!"', shell=True)
;shell=False也可以(诀窍是不要拆分参数)。Cygwin的Python在使用shell=True时无法按预期工作,并且在使用shell=False时,您将在任何双引号之前获得反斜杠,并且在包含空格的参数周围有双引号。并非所有情况都有一个解决方案 :/ - Badr Elmers