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

时间:2017-12-15 10:25:13

标签: python subprocess python-2.6 xmllint

我得到了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>']

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

1 个答案:

答案 0 :(得分:2)

这里的字符串<<<是一个shell构造。使用shlex()时,命令行将被拆分为参数,就好像shell在那里一样,所以你不需要shell=True,但shlex没有 - 并且coulnd& - t - 知道你试图解析的东西是否还需要shell ......当然这正是问题所在。

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

shell=True

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

如果您真的陷入Python 2,请考虑切换到2.7,其中shlex几乎完全相同,尽管界面更加笨重。

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