44

我怎样才能扭转 a 的结果shlex.split?也就是说,在给定我希望引用的字符串的情况下,如何获得一个“类似于 Unix shell”的带引号的字符串?list

更新0

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

4

6 回答 6

29

我们现在(3.3)有一个shlex.quote函数。pipes.quote移动和记录的不是其他(使用的代码pipes.quote仍然有效)。有关整个讨论,请参见http://bugs.python.org/issue9723 。

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

于 2011-07-29T13:39:08.747 回答
20

怎么用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'"

.

于 2011-01-20T15:11:33.110 回答
10

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

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

https://bugs.python.org/issue22454

于 2018-04-25T12:49:03.353 回答
10

它是python 3.8 中的shlex.join()

于 2019-10-15T11:36:26.173 回答
6

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

于 2011-07-24T04:37:10.977 回答
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 扩展,而不是像使用单引号一样逐字打印。

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

于 2021-06-29T12:04:39.290 回答