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

标签 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 的输入,那么为什么它仍在等待输入?我一直在尝试调试这个问题,但没有找到任何具体的方法来解决这个问题。任何指示都会有很大帮助

最佳答案

这里的字符串 <<< 是一个 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 ,您必须考虑如何转义输入字符串中的任何单引号,或者接受它们会导致语法错误的事实,所以也许诱惑是当第一个替代方案更加清晰和简单时,这里的效果不是很强)。

关于python:使用 xmllint 时子进程通信无限期等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47830301/

相关文章:

python - 如何 "overload"python的打印功能 "globally"?

python - 使用 Tkinter 等待一定时间

随机更改类型或变量的 Python 解释器

两个子进程之间的 Python 管道输出

python - 缺少子进程命令的输出

python - 更新字典整数成员时避免双重查找

python - 从源代码安装 Python 并且无法导入 Tkinter - 如何安装?

python - 如果某个时间正在执行方法,则重复

python - Django - 在 apache 每个请求创建的所有进程之间共享 RabbitMQ 连接?

java - 写入 java 子进程