使用 Python 将包含双引号的参数传递给子进程

Posted

技术标签:

【中文标题】使用 Python 将包含双引号的参数传递给子进程【英文标题】:Passing arguments which include double quotes to subprocess using Python 【发布时间】:2013-06-01 20:08:48 【问题描述】:

我正在寻找一种方法将包含双引号的参数传递给 python 的子进程模块,而双引号不会被转义。

当引号围绕 arg 时,我已经看到这个问题被问了几次,但答案通常是删除引号。我遇到的问题是引号是参数的一部分,并且必须传递给脚本而不在每个引号前加上反斜杠

示例:

我正在调用 subprocesTest.bat,这是一个简单的批处理脚本,它接受一个参数并回显它:

echo "%~1"

我使用包含引号的 arg 从 python 调用批处理脚本:

import subprocess
test_string = 'Bill said "Hi!"'
cmd = ["subprocesTest.bat",
       test_string
       ]

p = subprocess.Popen(cmd)
p.wait()

预期输出:

“比尔说“嗨!””

实际输出:

“比尔说“嗨!””

从命令行调用相同的批处理脚本时,我可以得到预期的输出,如下所示:

subprocesTest.bat "比尔说“嗨!”"

查看源码,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('\\"')

所以我有两个问题...

是否可以将 arg 传递给包含双精度的子进程 不加反斜杠的引用 如果不可能,有人可以向我解释为什么该功能 是这样设计的?函数文档字符串中的第三项 似乎表明我可以通过在前面加上一个字面引用 反斜杠,但这不会产生我正在寻找的行为。 我读错文档了吗?

以下是提出此问题的其他线程,并且通过不使用引号来解决:

Passing double quotation marks to a command from Python using the subprocess module How can I tell subprocess to stop escaping my quotes?

对于我实际上想在我的论点中传递引号的情况,我没有看到任何响应

【问题讨论】:

Passing double quote shell commands in python to subprocess.Popen()?的可能重复 我在 Windows 上找到的解决这个问题的唯一方法是使用 shell=True 而不是拆分 args ,Popen('subprocesTest.bat "Bill said "Hi!"', shell=True) ; shell=False 也有效(诀窍是不拆分参数)。 cygwin 的 python 将无法按预期使用 shell=True 和 shell=False 您将在任何双引号之前获得反斜杠,并在包含空格的 args 周围获得双引号。没有一种解决方案适用于所有情况:/ 【参考方案1】:

1) 是的,但可能不在 Windows 上和/或使用 .bat 文件。例如,当您运行与此等效的 windows 时会发生什么:

import subprocess

test_string = 'Bill said "Hi!"'

cmd = ["./myprog.py",
       test_string
       ]

p = subprocess.Popen(cmd)
p.wait()

myprog.py:

#!/usr/bin/env python

import sys

print '""'.format(sys.argv[1])

2) 好吧,以下似乎有点模棱两可:

"Bill said "Hi!""

那是引用的字符串吗:

"Bill said " 

后跟不带引号的字符串:

Hi!

后跟一个带引号的空白字符串:

""

?

【讨论】:

1) 您的 myprog.py 示例有效,只是因为 subprocess 在我认为用于在 python 读取参数时转义双引号的反斜杠之前添加了反斜杠。如果我从 Windows 命令行调用相同的 myprog.py 脚本并将 "Bill said "Hi!"" 作为 arg 传递,则 Hi! 周围的引号!消失。我想这就是反斜杠总是在双引号之前的原因 2) 这是一个很好的观点。我不确定 Windows 命令行是如何解释争论的,我只知道它在通过子进程时的解释不同。也许一个更好的例子是一个将测量值作为参数的简单脚本。我想使用子进程传入 16" 以表示 16 英寸,但子进程将我的参数转换为 16\",这不是我的距离批处理脚本所期望的

以上是关于使用 Python 将包含双引号的参数传递给子进程的主要内容,如果未能解决你的问题,请参考以下文章

将参数传递给nodejs中的子进程,这些参数在execFile方法中具有一些依赖性

如何在 fork() 之后将命令行参数传递给子进程

有没有办法在 CodeIgniter *不*使用 ActiveRecord 的情况下将参数传递给查询?

使用引号将参数传递给 SQL Server SP

Visual Studio代码launch.json runtimeArgs在参数中带有双引号

MS Access,如何将参数传递给子查询?