如何通过 Python 子进程模块将反斜杠作为参数传递?

How to pass a backslash as an argument via Python subprocess module?

我想使用 Python 的子进程来调用需要将路径作为参数传入的命令行程序。因为这是在 Windows 上,所以路径包含反斜杠。我已经尝试了很多选项,其中一些选项设置为打印出从子进程接收到的路径参数:

转义反斜杠:

>>> cmd = ['f:\code\Util.exe', '-i', 'c:\Users\paul\data.xml']
>>> subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> subprocess.communicate()
('Input path: c:\Users\paul\data.xml\n', '...')

单反斜杠,原始格式:

>>> cmd = ['f:\code\Util.exe', '-i', r'c:\Users\paul\data.xml']
>>> subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> subprocess.communicate()
('Input path: c:\Users\paul\data.xml\n', '...')

单反斜杠:

>>> cmd = ['f:\code\Util.exe', '-i', 'c:\Users\paul\data.xml']
>>> subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> subprocess.communicate()
('Input path: c:\Users\paul?5data.xml', '...')

在每种情况下,反斜杠都作为双反斜杠传递给 Windows 程序。有什么方法可以将单个反斜杠传递给被调用的程序吗?

第一种形式,将它们加倍,应该有效。但是请注意,当 Python 显示引号中的字符串时,它会 add 转义。例如,如果您键入 '\',解释器会显示完全相同的内容。但实际上它是一个反斜杠。您可以通过 len('\')print '\'.

来查看

所以我的问题是,您是否确定反斜杠被加倍了,或者 Python 只是在显示它们时转义了它们?

您对输出感到困惑。 Popen.communicate() 给你一个 tuple,包含 stdout 和 stderr 流。因为您得到一个元组,所以该元组的内容通过 repr() 函数显示。您的 字符串值 不包含双反斜杠,但由于此类反斜杠在 Python 字符串文字中具有特殊含义,因此它们以 Python 文字形式显示为加倍:

>>> value = r'foo\bar'
>>> value
'foo\bar'
>>> print value
foo\bar
>>> print (value,)  # tuple
('foo\bar',)
>>> print (value,)[0]  # back to one string
foo\bar

换句话说:这里没有问题,你得到的是 单个 反斜杠,但是 Python 给你文字符号表示(为了便于调试)。

更好的方法是使用 shlex 拆分字符串并在命令中使用列表。

您可以找到一个示例 here,如下所示。

>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!