由于实际需求,需要用到subprocess模块进行调用exe程序,并向子进程输入一些数据。在实际操作中遇到了不少困惑,记录一下。python版本为2.6,并已配置好python的环境变量。
首先看一个简单的demo。
以下是test.py的内容,主要是从IO获取两次输入,然后打印显示输入信息。
def main(): a = raw_input('a:') b = raw_input('b:') print 'a=' + a print 'b=' + b pass if __name__ == "__main__": main()以下是testforsubprocess.py的内容,以创建一个test.py运行实例作为子进程,并往子进程的输入端输入1和qq两个字符串,最后再获取输出端的信息。
import subprocess def myTest(): cmd = 'python test.py' if cmd != None: c = cmd print c p = subprocess.Popen(c,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) p.stdin.write('1\n') p.stdin.write('qq\n') while True: buff = string.strip(p.stdout.readline()) if buff == '' : print '=======================' print 'completed' print '=======================' break else: print buff passpass myTest()运行结果如下:
python test.py a:b:a=1 b=qq ======================= install completed =======================class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
在 subprocess.Popen()方法中,这个例子中最主要的参数是args、stdin和stdout。args给定的是一个可执行的命令,这里注 意了,python环境变量要配置好。而stdin和stdout就是接下来的重点了。在这个例子中,stdin和stdout都设置为PIPE,输入和 输出都能够正常运行。在参考了网络上诸多的例子之后,我才明白,stdin和stdout也可以设置为文件对象。如下所示:
def myTest(): cmd = 'python test.py' if cmd != None: c = cmd print c myinput = open('myinput.in') myoutput = open('myoutput.out','w') p = subprocess.Popen(c,shell=True,stdin=myinput,stdout=myoutput,stderr=subprocess.PIPE) pass输 入端变成了myinput.in,myinput.in文件就两行数据,一行是1,一行是qq;输出端变成了myoutput.out。程序依旧正常完 成。查看myoutput.out文件,也是两行信息,a:b:a=1和b=qq。单单只改变stdin为文件,或者单单只改变stdout为文件,程序 也能正常完成。如此就说明了设置为文本与PIPE是类似的。
根据官网文档提示:
Warning Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.应该尽可能的使用communicate(),故尝试一下。
def myTest(): cmd = 'python test.py' if cmd != None: c = cmd print c p = subprocess.Popen(c,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) output = p.communicate(input='1\nqq\n')[0] print output pass输出信息与之前的一致,如此方明白输入信息可以一并和在一起输入。就如同第一个小例子的p.stdin.write('1\n')和p.stdin.write('qq\n')可以一并写为p.stdin.write('1\nqq\n')。
如此看起来,似乎subprocess应用起来还是比较简单的。而实际中,让小弟我无可奈何。
由 于我想调用的exe程序并非如例子中如此简单,因此类似的照猫画虎已经不管用了,总是造成死锁,让我很是郁闷。最后才有一点点感悟,调用的exe程序,第 一个输入也只是简单的判断,但之后的输入对于程序而言可能需要几十毫秒的运行时间,从我手动执行该exe程序可以感受到。最后尝试了在每次输入时加入 time.sleep()来暂时解决该现象。
import subprocess import time def myTest(): cmd = 'exe程序的绝对路径' if cmd != None: c = cmd print c p = subprocess.Popen(c,shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) p.stdin.write('input message\n') time.sleep(0.5) p.stdin.write('input message\n') time.sleep(0.5) p.stdin.write('input message\n') time.sleep(0.5) while True: buff = string.strip(p.stdout.readline()) if buff == '' : print '=======================' print 'completed' print '=======================' break else: print buff passpass myTest()subprocess的确是一个很强大的模块,目前尚有很多不解之处,先记录之。待有所突破,继续更新。
转载于:https://www.cnblogs.com/mitingmai/p/3341214.html
相关资源:JAVA上百实例源码以及开源项目