在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"'