2015-02-05 4 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

ответ

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

+0

Чтобы прояснить это, дело не в том, что функция работает с yield-statement. Скорее, он не будет работать вообще, пока он не будет повторен. Биты перед оператором yield также не запускаются. –

+0

Пожалуйста, добавьте ВСЕ ОТКАЗ ОТ CAPSLOCK, если вы сознательно используете сломанный код. – jfs

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) 

Чтобы отбросить стандартный вывод/ребенка STDERR вместо сохранения, использования 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.

Смежные вопросы