=Start=
缘由:python中的 subprocess 模块允许你派生出新的进程,并通过pipe连接它们的标准输入/标准输出/标准出错,获取子进程的返回状态码。subprocess模块是被设计用来替代下面几个比较老的模块和函数的:
os.system os.spawn* os.popen* popen2.* commands.*PEP 324 且 PEP324 明确推荐使用subprocess模块
正文:在使用subprocess模块中的函数创建子进程的时候,要注意:
在创建子进程之后,父进程是否暂停,并等待子进程运行; 函数返回什么; 当returncode不为0时,父进程如何处理。 小结: 1.阻塞式,且不需要输出结果 p = subprocess.Popen(); p.communicate()/p.wait() subprocess.call() 2.阻塞式,要检查子进程执行状态 subprocess.call() subprocess.check_call() subprocess.check_output() 3.阻塞式,要检查子进程执行状态,且要查看错误原因 subprocess.check_output() 4.阻塞式,手动检查子进程执行状态 p = subprocess.Popen(cmd, shell=True) while p.poll() is None: time.sleep(1) if p.returncode != 0: print('"{0}" exec failed.'.format(cmd)) 5.非阻塞式 p = subprocess.Popen() #常见用法 try: p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except (OSError, ValueError) as e: print("%r failed, reason %s" % (cmd, str(e))) return -1 stdout_data, stderr_data = p.communicate() if p.returncode != 0: print("%r failed, status code %s stdout %r stderr %r" % (cmd, p.returncode, stdout_data, stderr_data))subprocess模块提供的常用函数
subprocess.call()
父进程等待子进程完成 返回退出信息(returncode,相当于exit code)subprocess.check_call()
父进程等待子进程完成 返回0 检查退出信息,如果returncode不为0,则抛出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try…except…来检查(见Python错误处理)。subprocess.check_output()
父进程等待子进程完成 返回子进程向标准输出的输出结果 检查退出信息,如果returncode不为0,则抛出错误subprocess.CalledProcessError,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try…except…来检查。subprocess.Popen对象
实际上,上面的三个函数都是基于Popen()的封装(wrapper)。这些封装的目的在于让我们容易使用子进程。当我们想要更个性化我们的需求的时候,就需要使用Popen类,该类生成的对象用来代表子进程。
与上面的封装不同,Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待(也就是阻塞block):
importsubprocess child = subprocess.Popen(["ping", "-c", "5", "www.baidu.com"]) print("parent process")从运行结果中看到,父进程在开启子进程之后并没有等待child的完成,而是直接运行print。
对比等待的情况:
importsubprocess child = subprocess.Popen(["ping", "-c", "5", "www.baidu.com"]) child.wait() print("parent process")Popen.poll() # 可用于检查子进程状态
检查子进程是否已终止。设置并返回 returncode attribute.
Popen.wait() # 可用来阻塞父进程,等待子进程执行完毕
等待子进程终止。设置并返回 returncode attribute.
Popen.pid
子进程的进程号 。如果你设置了 shell=True 选项,则返回的是派生shell的进程号
Popen.returncode
子进程的返回值,由 poll() 和 wait() 进行设置(间接的也被 communicate() 设置) ,当值为 None 时表明进程还未终止。(在Unix系统中若返回 -N 则表明进程是被通过N号信号给终止掉的)
subprocess模块中的异常
https://docs.python.org/2/library/subprocess.html#exceptions
OSError #当尝试执行一个并不存在的文件时会抛出该错误,在应用中应该注意该异常 ValueError #当在调用Popen时使用了不合法的参数会抛出该错误 CalledProcessError #在调用 check_call() 和 check_output() 时,如果程序执行失败则会抛出该错误 参考链接: Python标准库06 子进程 (subprocess包) https://docs.python.org/2/library/subprocess.html http://stackoverflow.com/questions/89228/calling-an-external-command-in-python http://stackoverflow.com/questions/12713801/python-2-7-3-process-popen-failures http://www.cyberciti.biz/faq/python-run-external-command-and-get-output/=END=