【问题标题】:shlex preserving double quotes?shlex 保留双引号?
【发布时间】:2016-02-08 16:46:50
【问题描述】:

我正在使用Popenshlex 作为带有--exclude 标志的yum 命令来传递要排除的软件包列表。出于某种原因,shlex 似乎没有保留双引号。任何指针我该怎么做?

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

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

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

【问题讨论】:

  • 在将字符串保留在双引号内时,这似乎有效。任何指针我如何进一步拆分此命令,不包括 --exclude 里面的内容? x = r'/usr/bin/yum update --exclude="foo bar baz*"' >>> print re.split(' (?=[)', x) ['/usr/bin/yum update - -exclude="foo bar baz*"']

标签: python shlex


【解决方案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 和直接程序调用将引号引入目标程序,并且 when 你可以控制输入字符串,那么你可以编写像这样的输入字符串(额外引用与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-syntax 编写它:x = r'/usr/bin/yum update --exclude="\"foo bar baz*\\""'


第四,如果您想将带有引号的 given 输入字符串带入目标程序,那么您需要使用自定义 shell 语法 - 例如通过正则表达式:

>>> 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*"']

【讨论】:

    猜你喜欢
    • 2021-09-28
    • 2017-08-12
    • 2014-07-28
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 2020-12-13
    • 2021-05-14
    • 2021-11-11
    相关资源
    最近更新 更多