2015-02-05 27 views
2

我有一个试图执行外部命令的小脚本。但由于某种原因,我执行该命令的功能正在被完全跳过!似乎没有错误提出,它只是不执行。我在里面有一些调试打印语句来验证函数是否进入,但他们从不打印。我在它外面有一个打印语句来验证脚本没有死掉。那么是什么给了?为什么我的Python函数被跳过?

from xml.etree import ElementTree as et 
import subprocess 

pomFileLocation = "pom.xml" 
uiAutomationCommand = "mvn clean install" 
revertPomFileCommand = "git checkout pom.xml" 
profileToSetToDefault = "smoketest" 

def modifyxml(datafile, value): 
    print("modifying " + datafile) 
    tree = et.parse(datafile) 
    rootNodes = tree.getroot() 
    for node in rootNodes: 
     if "profiles" in node.tag: 
      for profile in node.iter(): 
       foundIt = False 
       for param in profile.iter(): 
        if "id" in param.tag and profileToSetToDefault in param.text: 
         foundIt = True 
         break 
       if foundIt == True: 
        for param in profile.iter(): 
         if "activation" in param.tag: 
          for child in param.iter(): 
           if "activeByDefault" in child.tag: 
            child.text = value 
            tree.write(datafile) 
            return 

def runExternalCommand(comm): 
    print("running command " + comm) 
    p = subprocess.Popen(comm, bufsize=-1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0] 
    print(str(p)) 
    while(True): 
     print("still running") 
     retcode = p.poll() 
     line = p.stdout.readline() 
     yield line 
     if(retcode is not None): 
      print("Exiting") 
      break 
    return 

if __name__ == '__main__': 
    modifyxml(pomFileLocation, "true") 
    #runExternalCommand(uiAutomationCommand) 
    runExternalCommand(revertPomFileCommand) 
    print("finished") 
+0

你在哪里得到'runExternalCommand()'定义?它被打破。请留下您的评论,以便其他人不会使用破损的代码。 [我的答案提供了一些替代方法](http://stackoverflow.com/a/28352727/4279) – jfs 2015-02-05 19:49:47

回答

2

runExternalCommand使用yield,所以如果你希望它一路执行到底,你应该称呼它for something in runExternalCommand(revertPomFileCommand):。或者直接删除yield这一行,因为你似乎并不需要它。

def runExternalCommand(comm): 
    print("running command " + comm) 
    p = subprocess.Popen(comm, bufsize=-1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0] 
    print(str(p)) 
    while(True): 
     print("still running") 
     retcode = p.poll() 
     line = p.stdout.readline() 
     yield line 
     if(retcode is not None): 
      print("Exiting") 
      break 
    return 

if __name__ == '__main__': 
    modifyxml(pomFileLocation, "true") 
    #runExternalCommand(uiAutomationCommand) 
    for line in runExternalCommand(revertPomFileCommand): 
     pass 
    print("finished") 

或者

def runExternalCommand(comm): 
    print("running command " + comm) 
    p = subprocess.Popen(comm, bufsize=-1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0] 
    print(str(p)) 
    while(True): 
     print("still running") 
     retcode = p.poll() 
     line = p.stdout.readline() 
     if(retcode is not None): 
      print("Exiting") 
      break 
    return 

if __name__ == '__main__': 
    modifyxml(pomFileLocation, "true") 
    #runExternalCommand(uiAutomationCommand) 
    runExternalCommand(revertPomFileCommand) 
    print("finished") 
+0

啊。这就是我从互联网上盲目复制和粘贴的结果。我不知道收益会做到这一点。我删除它,现在它可以工作。谢谢! – user2623609 2015-02-05 18:50:24

+0

为了澄清,这不是函数运行到yield-statement。相反,直到它迭代完成才会运行。 yield-statement之前的位也不会运行。 – 2015-02-05 18:50:25

+0

如果您故意使用破损的代码,请添加所有CAPSLOCK免责声明。 – jfs 2015-02-05 19:54:34

1

由于@Kevin said,主要(但不是唯一的)问题是runExternalCommand是发电机。要消耗它,你可以运行:print(list(runExternalCommand(revertPomFileCommand)))

虽然功能runExternalCommand()被打破:没有一点叫p.stdout.readline().communicate()回报(子进程结束后等待并立即返回整个输出)。

目前尚不清楚你想要得到例如,运行git命令和存储其在一个可变输出什么结果,你可以使用subprocess.check_output()

from subprocess import check_output, STDOUT 

output = check_output("git checkout pom.xml".split(), 
         stderr=STDOUT, universal_newlines=True) 

要放弃孩子的标准输出/标准错误,而不是保存,使用subprocess.check_call()

from subprocess import check_call, DEVNULL, STDOUT 

check_call("git checkout pom.xml".split(), 
      stdout=DEVNULL, stderr=STDOUT) 

对于代码示例,以读取输出,同时子进程仍在运行,见Constantly print Subprocess output while process is running