【问题标题】:Passing double quotation marks to a command from Python using the subprocess module使用 subprocess 模块将双引号传递给 Python 中的命令
【发布时间】:2013-04-19 22:40:35
【问题描述】:

我在 Python 脚本中使用了一个命令行程序来处理将内部版本号标记到可执行文件上。

这是命令行程序:http://www.elphin.com/downloads/stampver/

我的问题是程序在其参数之一中使用双引号 ("),而我用来调用该程序的 Python 子进程模块在执行程序时一直在双引号前加上反斜杠。这会导致程序由于语法错误而失败。

它需要一个类似的命令:StampVer.exe -nopad -k -f"0.1.4491.0" <ExeFile>.exe

而 Python 正在执行:StampVer.exe -nopad -k -f\"0.1.4491.0\" <ExeFile>.exe

我尝试了一些我在 StackOverflow 上发现的类似问题的方法,例如将字符串标记为原始字符串或在 Python 中的引号前添加反斜杠;这只会在命令行上产生三个反斜杠而不是一个,因为 Python 会尝试转义反斜杠和双引号。

我应该使用子进程模块以外的东西来完成此任务,还是 Python 中的所有这些类型的模块都遵循相同的转义字符规则?我可以做些什么来告诉子进程去除转义字符或根本不添加它们?

编辑

这就是我从 Python 调用子进程的方式:

def set_file_version(version_number, filepath):

    try:
        file_version_arg = '-f"{0}"'.format(version_number)
        cmd_line = ["StampVer.exe", "-nopad", "-k", file_version_arg, filepath]
        subprocess.check_output(cmd_line)

    except subprocess.CalledProcessError as e:
        if e.returncode == 1:
            pass
        else:
            raise e

StampVer 然后返回:

error: Invalid -f parameter. Try -f"0.0.0.0" Use StampVer -? for help

【问题讨论】:

  • 您能告诉我们您是如何使用 Popen 的吗?带或不带 shell=True,使用字符串或元组作为命令
  • 你是怎么看到\的?是来自 print(command) 还是 repr(command)?您能否也发布失败消息。
  • 我没有使用 Popen 作为我的编辑显示;我将 check_output 与命令行字符串列表一起使用。我看到了反斜杠,而不是直接调用 StampVer.exe,而是创建了 StampVer.bat,它为我调用它并将版本和 exe 路径作为参数。然后在调用 StampVer.exe 之前,我回显了从 Python 发送的版本和 exe 路径。此外,我阅读了一个名为 list2cmdline 的未记录子进程函数,该函数将获取命令行列表并将其转换为命令行字符串。这也包含反斜杠字符。

标签: python string escaping subprocess double-quotes


【解决方案1】:

试试这个脚本 sub.py:

#! /usr/bin/python

import sys
from subprocess import check_output

if len(sys.argv) > 1:
    print sys.argv
else:
    print check_output((sys.argv[0], '-f"1234"'))

然后运行它:

./sub.py

它返回我们给的东西:

['./sub.py', '-f"1234"']

所以我猜check_output可以正常工作,问题可能来自StampVer.exe如何处理参数,你可以试试

file_version_arg = '-f{0}'.format(version_number)

【讨论】:

  • 该脚本在 Windows 上对我不起作用,因为它在尝试通过 check_output 运行 sub.py 时返回 WindowsError 异常。我认为您在打印的参数中没有看到任何反斜杠的原因是因为 Python 在从命令行读取时知道如何正确处理它们,或者根据 #! /usr/bin/python 在文件的顶部,在 linux 系统上规则是不同的。
【解决方案2】:

我的解决方案最终成为一种逃避。尽管 StampVer 的文档在所有示例中都显示了上述版本号的格式,但事实证明,您可以将引号全部放在一起,甚至将其从 -f 开关中隔开,它仍然会被接受。

我将把它称为我的答案,但我仍然认为能够通过子进程传递引号是一个值得解决的问题。如果有人有一个可以真正解决最初问题的答案,请发布它,我会标记它。

【讨论】:

    猜你喜欢
    • 2013-02-02
    • 2018-11-17
    • 2018-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多