到 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:10:25  来源:igfitidea点击:

Python module to shellquote/unshellquote?

pythonshellquoting

提问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.quoteis now shlex.quotein 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 list2cmdlinefunction supplied by Python works as advertised on Windows]

对于 shell 引用,这是有效的:我已经在 Posix 上对其进行了严格的测试。[我假设list2cmdlinePython 提供的函数像 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.callsubprocess.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 quotefunction is available for quite some time (Python 2.7?) -- the major drawback is it moved from pipemodule to shlexbetween 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