[英]On Windows, how can I protect arguments to shell scripts using Python 2.7 subprocess?
Consider for example the following Python code: 考虑以下Python代码:
subprocess.call([r'.\tst.bat', '"1|2"'])
Here I've put double quotes around the argument to tst.bat, in order to protect '|' 在这里,我在tst.bat的参数周围放了双引号,以保护'|' from the shell since tst.bat will ultimately be run via the Windows shell.
从shell开始,因为tst.bat最终将通过Windows shell运行。 However, if there are double quotes in arguments, subprocess in Python 2.7 escapes them.
但是,如果参数中有双引号,则Python 2.7中的子进程会逃避它们。 The result is that tst.bat receives this argument: \\"1|2\\".
结果是tst.bat接收到这个参数:\\“1 | 2 \\”。
How can I escape the argument "1|2" so that it's passed untransformed to tst.bat? 如何逃避参数“1 | 2”,以便它传递给tst.bat?
Subprocess module on Windows in case of a list of arguments given to the call
method transforms this list into a string using list2cmdline
function. 在给出的参数列表的情况下,在Windows子模块的
call
方法转换这个名单到使用字符串list2cmdline
功能。 In the docstring of this function one can read: 在这个函数的docstring中可以读到:
3) A double quotation mark preceded by a backslash is interpreted as a literal double quotation mark.
3)以反斜杠开头的双引号被解释为文字双引号。
According to this the solution of your problem should look like this 根据这个,你的问题的解决方案应该是这样的
subprocess.call([r'.\tst.bat', r'\"1|2\"'])
However it seems like there's a mismatch between documentation and implementation of list2cmdline
function; 然而,似乎文档和
list2cmdline
函数的实现之间存在不匹配;
Python 2.7.4 (default, Apr 6 2013, 19:55:15) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> print subprocess.list2cmdline([r'\"1|2\"'])
\\\"1|2\\\"
The same behavior is in Python 3.3.1. Python 3.3.1中的行为相同。 I raised a bug at http://bugs.python.org/issue18649
我在http://bugs.python.org/issue18649上提出了一个错误
UPDATE UPDATE
It turns out I was confused by very misleading docstring of list2cmdline
function - see http://bugs.python.org/issue18649 for details. 事实证明我对
list2cmdline
函数的误导性文档字符串感到困惑 - 有关详细信息,请参阅http://bugs.python.org/issue18649 。
The sequence of arguments passed to subprocess.call
is translated by list2cmdline
function which is concerned only with the quoting mechanism used by MS C runtime and not by quoting mechanism used by cmd.exe. 传递给自变量的序列
subprocess.call
由翻译list2cmdline
其与由MS C运行时,而不是由通过引用cmd.exe的使用机构中使用的引用机制只关注功能。 This makes passing arguments - which are later to be interpreted by cmd.exe - to subprocess.call
as a list either very awkward or impossible. 这使得传递参数 - 后来被cmd.exe解释 - 传递给
subprocess.call
作为一个非常笨拙或不可能的列表。
There's one more chance to get it working in this case, though. 但是,在这种情况下还有一次机会让它运转起来。
list2cmdline
double quotes every argument with a space or tab inside. list2cmdline
double引用内部有空格或制表符的每个参数。 If having a space at the end of your argument does not break the batch file you can add it at the end forcing double quoting as you wanted. 如果在参数末尾有空格不会破坏批处理文件,则可以在最后添加它以强制双引号。
>>> import subprocess
>>> print subprocess.list2cmdline(['1|2 '])
"1|2 "
This (or a similar problem) has been reported as a bug. 这个(或类似的问题)已被报告为一个错误。
References: 参考文献:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.