python:使用xmllint时,子进程通信等待无限期

问题描述 投票:1回答:1

我得到了python 2.6,它有一个旧版本的toprettyxml(),它没有按预期进行我的xml格式化。因此我试图使用子进程调用xmllint。这是我的简化代码。

      xmlParseCmd = "xmllint -format - <<< '%s'" % '<?xml version="1.0" encoding="UTF-8"?> <insertion> <mytag>123456</mytag> <mytag2>789</mytag2> </insertion>'
      print shlex.split(xmlParseCmd)
      pxmlParser = subprocess.Popen(shlex.split(xmlParseCmd), stdout=subprocess.PIPE)
      pretty_xml = pxmlParser.communicate()[0]
      print pretty_xml

程序在以下输出后无限期挂起。我猜它在等待一些输入。

 -> python ~/myscripts/resources/test_xtract.py
['xmllint', '-format', '-', '<<<', '<?xml version="1.0" encoding="UTF-8"?> <insertion> <mytag>123456</mytag> <mytag2>789</mytag2> </insertion>']

我已经使用了一个here字符串作为xmllint的输入,那为什么它还在等待输入呢?我正在尝试调试这个但是havnt找到了解决这个问题的具体方法。任何指针都会有很大的帮助

python subprocess python-2.6 xmllint
1个回答
2
投票

这里的字符串<<<是一个shell结构。当使用shlex()时,命令行将被拆分为参数,就像shell在那里一样,所以你不需要shell=True,但是shlex不会 - 并且不能 - 知道你试图解析的是什么仍然需要shell ....这当然是这里的问题。

如果你真的很绝望,你当然可以调用shell来简单地打印一个字符串(在这种情况下,取出shlex并用shell=True传递长字符串),但是,你知道,Python也可以这样做。

from subprocess import run, PIPE

xml = '<?xml version="1.0" encoding="UTF-8"?> <insertion> <mytag>123456</mytag> <mytag2>789</mytag2> </insertion>'
xmllint = run(['xmllint', '-format', '-'], input=xml, stdout=PIPE, universal_newlines=True)
print(xmllint.stdout)

使用这个简单的静态命令,shlex有点矫枉过正,但它当然会让你无法确定shell将如何解析你的命令行。我刚刚在这里对命令进行了硬编码。

如果你真的陷入Python 2,考虑切换到2.7,其中subprocess.check_output()几乎完全相同,尽管界面更笨重。

如果你真的陷入Python 2.6,那么直接与Popen()进行交互,这个过程就像你现有的代码一样 - 你只需要改变它来传递p = Popen(['xmllint', etc]); p.communicate('string')的输入,或者陷入罪恶的诱惑Popen("xmllint etc <<<'%s'" % string, shell=True)(虽然在后一种情况下,没有shlex,你将不得不考虑如何转义输入字符串中的任何单引号,或者说它们会导致语法错误这一事实,所以也许诱惑不是很大这里很强大,当第一个选择更加清晰和简单时)。

© www.soinside.com 2019 - 2024. All rights reserved.