为什么我的 python 函数被跳过了?

Why is my python function being skipped?

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

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" )

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" )

一样,主要(但不是唯一)的问题是 runExternalCommand 是一个生成器。要使用它,您可以 运行: print(list(runExternalCommand(revertPomFileCommand))).

虽然函数 runExternalCommand() 被破坏了:在 .communicate() returns 之后调用 p.stdout.readline() 没有意义(后者等待 child 进程立即完成 returns 整个输出)。

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

from subprocess import check_output, STDOUT

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

要丢弃 child 的 stdout/stderr 而不是保存它,请使用 subprocess.check_call():

from subprocess import check_call, DEVNULL, STDOUT

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

对于代码示例,要在 child 进程仍在 运行ning 时读取输出,请参阅 Constantly print Subprocess output while process is running