我怎样才能扭转 a 的结果shlex.split
?也就是说,在给定我希望引用的字符串的情况下,如何获得一个“类似于 Unix shell”的带引号的字符串?list
更新0
我找到了一个 Python 错误,并在此处提出了相应的功能请求。
我怎样才能扭转 a 的结果shlex.split
?也就是说,在给定我希望引用的字符串的情况下,如何获得一个“类似于 Unix shell”的带引号的字符串?list
我找到了一个 Python 错误,并在此处提出了相应的功能请求。
我们现在(3.3)有一个shlex.quote函数。pipes.quote
移动和记录的不是其他(使用的代码pipes.quote
仍然有效)。有关整个讨论,请参见http://bugs.python.org/issue9723 。
subprocess.list2cmdline
是不应使用的私有函数。然而,它可以被转移shlex
并正式公开。另请参阅http://bugs.python.org/issue1724822。
怎么用pipes.quote
?
import pipes
strings = ["ls", "/etc/services", "file with spaces"]
" ".join(pipes.quote(s) for s in strings)
# "ls /etc/services 'file with spaces'"
.
有一个要添加的功能请求shlex.join()
,它会完全按照您的要求进行。不过,截至目前,它似乎没有任何进展,主要是因为它大多只是转发到shlex.quote()
. 在错误报告中,提到了一个建议的实现:
' '.join(shlex.quote(x) for x in split_command)
它是python 3.8 中的shlex.join()
subprocess
使用subprocess.list2cmdline()
. 它不是官方的公共 API,但在subprocess
文档中提到过,我认为使用起来非常安全。它比pipes.open()
(无论好坏)更复杂。
虽然shlex.quote在 Python 3.3 中可用,而shlex.join在 Python 3.8 中可用,但它们并不总是作为shlex.split
. 观察以下片段:
import shlex
command = "cd /home && bash -c 'echo $HOME'"
print(shlex.split(command))
# ['cd', '/home', '&&', 'bash', '-c', 'echo $HOME']
print(shlex.join(shlex.split(command)))
# cd /home '&&' bash -c 'echo $HOME'
请注意,在拆分然后加入之后,&&
令牌现在有单引号。如果你现在尝试运行命令,你会得到一个错误:cd: too many arguments
如果您subprocess.list2cmdline()
按照其他人的建议使用,它可以更好地与 bash 运算符一起使用,例如&&
:
import subprocess
print(subprocess.list2cmdline(shlex.split(command)))
# cd /home && bash -c "echo $HOME"
但是您现在可能会注意到引号现在是双引号而不是单引号。这会导致$HOME
被 shell 扩展,而不是像使用单引号一样逐字打印。
总之,没有 100% 万无一失的撤消方法shlex.split
,您必须选择最适合您的目的的选项并注意边缘情况。