首先,您的参数将通过正常方式正确到达目标程序的 argv/argc shlex.split(x)
- 如下所示:
>>> 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=True
在 Popen 上使用,并且可以传递命令字符串 unsplit:
p = subprocess.Popen(x, shell=True, ...)
:这种方式字符串x
由shell直接解释 - 例如bash。但是涉及一个额外的 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-syntax 编写它: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*"']