Python3:shell引用比shlex.quote()输出复杂吗



python3.8中,我有以下代码:

import shlex
item = "ABC'DEF"
quoteditem = shlex.quote(item)
print(quoteditem)

这是输出:

'ABC'"'"'DEF’

在这个网页上很难辨别双引号和单引号,所以这是对打印内容的描述:

single-quote
ABC
single-quote
double-quote
single-quote
double-quote
single-quote
DEF
single-quote

当然,这是一个正确的shell引用,但它并不是唯一可能的shell引用方式,而且它过于复杂。

另一种可能性很简单:

"ABC'DEF";

还有第二种可能性:

ABC\'DEF

我更喜欢这些更简单的版本。我知道如何编写python代码,将复杂的版本转换为这些更简单的形式之一,但我想知道是否有一个现有的python函数可以执行这种更简单的shell引用。

提前感谢您的任何建议。

这是一个答案。它没有提供">。。。已经存在的CCD_ 4函数可以执行这种更简单的shell引用";,正如我所要求的,因为现在python中似乎不存在这样的引用函数。然而,它确实展示了我是如何编码一个报价机制的,该机制提供了更简单的输出(对于python-3.6或更高版本(:

def shellquote(item):
if not item:
return "''"
# Pre-escape any escape characters                                                                                                                    
item = item.replace('\', r'\')
if "'" not in item:
# Contains no single quotes, so we can                                                                                                        
# single-quote the output.                                                                                                                    
return f"'{item}'"
else:
# Enclose in double quotes. We must escape                                                                                                    
# "$" and "!", which which normally trigger                                                                                                   
# expansion in double-quoted strings in shells.                                                                                               
# If it contains double quotes, escape them, also.                                                                                               
item = item.replace(r'$', r'$') 
.replace(r'!', r'!') 
.replace(r'"', r'"')
return f'"{item}"'

对于不支持f字符串的python的早期版本,可以使用format来代替那些f字符串。

下面是一些例子。左边的列显示了python程序中pythonString变量的赋值语句。右边的列显示了当从python程序中调用print(shellquote(pythonString))时,终端上将显示的内容:

pythonString='ABC"DEF'       printed output: 'ABC"DEF'
pythonString="ABC'DEF"       printed output: "ABC'DEF"
pythonString='ABC'DEF'      printed output: "ABC'DEF"
pythonString="ABC"DEF"      printed output: 'ABC"DEF'
pythonString='ABC\"DEF'     printed output: 'ABC\"DEF'
pythonString="ABC\'DEF"     printed output: "ABC\'DEF"
pythonString="AB'C$DEF"      printed output: "AB'C$DEF"
pythonString='AB'C$DEF'     printed output: "AB'C$DEF"
pythonString='AB"C$DEF'      printed output: 'AB"C$DEF'
pythonString="AB"C$DEF"     printed output: 'AB"C$DEF'
pythonString='A'B"C$DEF'    printed output: "A'B"C$DEF"
pythonString='A\'B"C$DEF'  printed output: "A\'B"C$DEF"

这并不是执行shell引用的唯一方法,但至少在许多情况下,输出比shlex.quote更简单。

shlex.quote针对性能进行了优化,因此输出是机器可读的,但对人眼来说不太好看。产生";漂亮的";字符串的较慢

当用双引号(对于shell(包裹字符串时,还需要转义$x$(x)!x等表达式

import re
_shell_quote_is_unsafe = re.compile(r'[^w@%+=:,./-]', re.ASCII).search
# note: [^...] = negated char class -> safe chars are w@%+=:,./-
_shell_quote_replace = re.compile(r'([\$"!])', re.ASCII).sub
def shell_quote(s: str):
"""
Return a shell-escaped version of the string *s*.
Wrap string in double-quotes when necessary.
Based on shlex.quote (wrap string in single-quotes)
"""
if not s:
return '""'
if _shell_quote_is_unsafe(s) is None:
return s
return '"' + _shell_quote_replace(r"\1", s) + '"'
# test
assert shell_quote('a"b\c$d$(e)!ftgnhri') == '"a\"b\\c\$d\$(e)\!ftgnhri"'

相关内容

  • 没有找到相关文章

最新更新