如何将shlex.split
的结果反转?也就是说,如何在给定带引号的字符串的情况下获得一个列表,该列表会"类似于Unix Shell", 给定我希望带引号的list
字符串?
更新0
我已经发现了一个Python bug,并提出了相应的功能请求here。
如何将shlex.split
的结果反转?也就是说,如何在给定带引号的字符串的情况下获得一个列表,该列表会"类似于Unix Shell", 给定我希望带引号的list
字符串?
我已经发现了一个Python bug,并提出了相应的功能请求here。
现在(3.3)我们有一个shlex.quote函数,它实际上就是pipes.quote
被移动并进行了说明(使用pipes.quote
的代码仍然有效)。请参见http://bugs.python.org/issue9723以了解整个讨论。
subprocess.list2cmdline
是一个私有函数,不应该使用。但是,它可以被移动到shlex
并正式公开。请参见http://bugs.python.org/issue1724822。
subprocess.list2cmdline()
为什么被指定为私有方法?它没有前置下划线,并且在官方文档中也有提及! - Daniel Fortunovshlex.quote
不适用于链式命令。例如,虚拟的 cmd = ['pwd', '&&', 'cd']
会产生错误的命令:"pwd '&&' cd"
。 - vedarsubprocess.list2cmdline()
看起来像是不同的命令,并且在链接符号方面表现正确,尽管它是为 Windows 设计的,但用户可以在 Popen
中传递列表(即使启用了 shell - shell=True
)。 - vedarshlex.quote
的实际示例会更好?在 https://bugs.python.org/issue22454 中,他们建议使用 ' '.join(shlex.quote(x) for x in split_command)
应该就足够了。 - Matthijs Kooijman使用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'"
.
pipes.quote
不适用于 Windows。Windows 需要双引号。 - Nux有一个功能请求,希望添加shlex.join()
,它将完全实现您所要求的功能。截至目前,似乎没有任何进展,因为它大多只是转发到shlex.quote()
。在错误报告中,提到了一种建议的实现方法:
' '.join(shlex.quote(x) for x in split_command)
subprocess
使用subprocess.list2cmdline()
。它不是官方公共API,但在subprocess
文档中提到,并且我认为它是相当安全的。它比pipes.open()
更复杂(好或坏都有可能)。
list2cmdline
仅在 Windows 上使用,因此它所执行的转义只适用于 Windows。 - Eric虽然Python 3.3中提供了shlex.quote方法,而Python 3.8中提供了shlex.join方法,但它们并不总是作为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
,您将不得不选择最适合您目的的选项并注意边缘情况。