我有一个试图执行外部命令的小脚本。但由于某种原因,我完全跳过了执行命令的功能!似乎没有出现任何错误,它只是没有执行。我在里面有一些调试打印语句来验证函数是否已输入,但它们从不打印。我在它之外有一个打印声明来验证脚本没有死亡。那是什么给出了什么?
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 :(得分: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" )
答案 1 :(得分: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)
要丢弃孩子的stdout / 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。