什么是shlex.split的反面?

时间:2011-01-20 14:33:12

标签: python shell split shlex

如何反转shlex.split的结果?也就是说,如果我希望引用list字符串,我如何获得"resemble that of a Unix shell"的带引号的字符串?

Update0

我找到了一个Python错误,并提出了相应的功能请求here

6 个答案:

答案 0 :(得分:26)

我们现在(3.3)具有shlex.quote功能。 pipes.quote已移动并记录(使用pipes.quote的代码仍然有效)。有关整个讨论,请参阅http://bugs.python.org/issue9723

subprocess.list2cmdline是一个不应该使用的私有函数。然而,它可以移至shlex并正式公开。另请参阅http://bugs.python.org/issue1724822

答案 1 :(得分:19)

如何使用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'"

答案 2 :(得分:6)

subprocess使用subprocess.list2cmdline()。它不是官方的公共API,但它在subprocess文档中提到过,我认为使用它非常安全。它比pipes.open()更复杂(无论好坏)。

答案 3 :(得分:2)

有一项添加shlex.join()的功能请求,可以完全按照您的要求进行操作。截至目前,似乎没有任何进展,主要是因为它主要只是前进到shlex.quote()。在错误报告中,提到了一个建议的实现:

' '.join(shlex.quote(x) for x in split_command)

请参阅https://bugs.python.org/issue22454

答案 4 :(得分:0)

它是python 3.8中的shlex.join()

答案 5 :(得分:0)

虽然 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 展开,而不是像使用单引号一样逐字打印。

总而言之,撤销 shlex.split 没有 100% 万无一失的方法,您必须选择最适合您的目的的选项并注意边缘情况。