到 shellquote/unshellquote 的 Python 模块?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/967443/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python module to shellquote/unshellquote?
提问by YGA
Is there anything in the Python standard library that will properly parse/unparse strings for using in shell commands? I'm looking for the python analog to perl's String::ShellQuote::shell_quote
:
Python 标准库中是否有任何内容可以正确解析/解解析字符串以在 shell 命令中使用?我正在寻找 perl 的 python 模拟String::ShellQuote::shell_quote
:
$ print String::ShellQuote::shell_quote("hello", "stack", "overflow's", "quite", "cool")
hello stack 'overflow'\''s' quite cool
And, even more importantly, something which will work in the reverse direction (take a string and decompose it into a list).
而且,更重要的是,一些可以反向工作的东西(取一个字符串并将其分解成一个列表)。
采纳答案by dnozay
pipes.quote
is now shlex.quote
in python 3.
It is easy enough to use that piece of code.
pipes.quote
现在shlex.quote
在python 3中。使用那段代码很容易。
https://github.com/python/cpython/blob/master/Lib/shlex.py#L281
https://github.com/python/cpython/blob/master/Lib/shlex.py#L281
That version handles zero-length argument correctly.
该版本正确处理零长度参数。
回答by YGA
Looks like
好像
try: # py3
from shlex import quote
except ImportError: # py2
from pipes import quote
quote("hello stack overflow's quite cool")
>>> '"hello stack overflow\'s quite cool"'
gets me far enough.
让我走得够远。
回答by John Wiseman
I'm pretty sure that pipes.quote is broken, and should not be used, because it does not handle zero-length arguments correctly:
我很确定 pipe.quote 已损坏,不应使用,因为它无法正确处理零长度参数:
>>> from pipes import quote
>>> args = ['arg1', '', 'arg3']
>>> print 'mycommand %s' % (' '.join(quote(arg) for arg in args))
mycommand arg1 arg3
I believe the result should be something like
我相信结果应该是这样的
mycommand arg1 '' arg3
回答by DomQ
To unquote, try shlex.split()
要取消引用,请尝试 shlex.split()
回答by Dave Abrahams
For shell quoting, this works: I've rigorously tested it on Posix. [I'm assuming that the list2cmdline
function supplied by Python works as advertised on Windows]
对于 shell 引用,这是有效的:我已经在 Posix 上对其进行了严格的测试。[我假设list2cmdline
Python 提供的函数像 Windows 上宣传的那样工作]
# shell.py
import os
if os.name == 'nt':
from subprocess import list2cmdline
def quote(arg):
return list2cmdline([arg])[0]
else:
import re
_quote_pos = re.compile('(?=[^-0-9a-zA-Z_./\n])')
def quote(arg):
r"""
>>> quote('\t')
'\\t'
>>> quote('foo bar')
'foo\ bar'
"""
# This is the logic emacs uses
if arg:
return _quote_pos.sub('\\', arg).replace('\n',"'\n'")
else:
return "''"
def list2cmdline(args):
return ' '.join([ quote(a) for a in args ])
The tests are here, if anyone cares.
测试在这里,如果有人关心的话。
回答by Alex
The standard library module subprocess has the list2cmdline function which does this, albeit according to Microsoft rulesso I am not sure how reliable it works in Unix-like environments for more complicated command lines.
标准库模块子进程具有执行此操作的 list2cmdline 函数,尽管根据Microsoft 规则,因此我不确定它在类 Unix 环境中对于更复杂的命令行的工作可靠性如何。
回答by Jerub
You should never have to shell quote. The correct way to do a command is to not do shell quoting and instead use subprocess.callor subprocess.Popen, and pass a list of unquoted arguments. This is immune to shell expansion.
您永远不必使用 shell 引用。执行命令的正确方法是不进行 shell 引用,而是使用subprocess.call或subprocess.Popen,并传递未引用参数的列表。这不受外壳扩展的影响。
i.e.
IE
subprocess.Popen(['echo', '"', '$foo'], shell=False)
If you want to unquote shell quoted data, you can use shlex.shlexlike this:
如果要取消引用 shell 引用的数据,可以像这样使用shlex.shlex:
list(shlex.shlex("hello stack 'overflow'\''s' quite cool"))
回答by Sylvain Leroux
The quote
function is available for quite some time (Python 2.7?) -- the major drawback is it moved from pipe
module to shlex
between 3.2 and 3.3.
该quote
函数已经可用了很长一段时间(Python 2.7?)——主要的缺点是它从pipe
模块移到shlex
了 3.2 和 3.3 之间。
You have to be prepared to handle both cases while importing that function:
在导入该函数时,您必须准备好处理这两种情况:
try:
from shlex import quote
except ImportError:
from pipes import quote