shlex保留双引号?

时间:2016-02-08 16:46:50

标签: python shlex

我正在使用带有Popen的{​​{1}}来获取带有shlex标志的yum命令,以传递要排除的包列表。出于某种原因,--exclude似乎没有保留双引号。任何指示如何解决这个问题?

shlex

关闭POSIX模式后,引号似乎放错了位置。

>>> import shlex
>>> x = '/usr/bin/yum update --exclude=\"foo bar baz*\"'   
>>> print shlex.split(x)
['/usr/bin/yum', 'update', '--exclude=foo bar baz*']

1 个答案:

答案 0 :(得分:1)

首先,您的参数已经通过普通shlex.split(x)在目标程序的argv / argc中正确到达 - 如下所示:

>>> x = '/usr/bin/yum update --exclude=\"foo bar baz*\"' 
>>> l = shlex.split(x); l
['/usr/bin/yum', 'update', '--exclude=foo bar baz*']
>>> p = subprocess.Popen(['python', '-c', "import sys;print(sys.argv)"] + l, stdout=subprocess.PIPE)
>>> p.stdout.read()
"['-c', '/usr/bin/yum', 'update', '--exclude=foo bar baz*']\r\n"

:shell上的引号用于将参数字符串保持在一起,以便在目标应用中正确分割;并且使用拆分参数,拆分已经完成。

其次,你可以在Popen上使用shell=True,你可以传递命令字符串unsplit:

p = subprocess.Popen(x, shell=True, ...)

:这样,字符串x由shell直接解释 - 例如庆典。但是涉及额外的shell进程并消耗资源和运行时间

第三,如果你真的希望通过shlex.split和直接程序调用获取引用目标程序,并且你可以控制输入字符串,那么你可以写像这样的输入字符串(额外引用与shell(-mode)相同):

>>> x = '/usr/bin/yum update --exclude="\\"foo bar baz*\\""' 
>>> l = shlex.split(x); l
['/usr/bin/yum', 'update', '--exclude="foo bar baz*"']
>>> p = subprocess.Popen(['python', '-c', "import sys;print(sys.argv)"] + l, stdout=subprocess.PIPE)
>>> print(p.stdout.read())
['-c', '/usr/bin/yum', 'update', '--exclude="foo bar baz*"']

(注意:输入字符串中的一个反斜杠使用python语法,除非你用r语法编写它:x = r'/usr/bin/yum update --exclude="\"foo bar baz*\\""'

第四,如果你想把带有引号的给定输入字符串放到目标程序中,那么你需要使用自定义shell语法 - 例如通过REGEX:

>>> x = '/usr/bin/yum update --exclude=\"foo bar baz*\"' 
>>> l = re.findall(r'(?:[^\s,"]|"(?:\\.|[^"])*")+', x); l
['/usr/bin/yum', 'update', '--exclude="foo bar baz*"']
>>> p = subprocess.Popen(['python', '-c', "import sys;print(sys.argv)"] + l, stdout=subprocess.PIPE)
>>> print(p.stdout.read())
['-c', '/usr/bin/yum', 'update', '--exclude="foo bar baz*"']