我得到了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找到了解决这个问题的具体方法。任何指针都会有很大的帮助
答案 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')
,你必须考虑如何转义输入字符串中的任何单引号,或者说它们会导致语法错误这一事实,所以当第一种选择更加清晰和简单时,这里的诱惑可能并不强烈。