介绍
subprocess模块用来创建新的进程,连接到其stdin、stdout、stderr管道并获取它们的返回码。
subprocess模块的出现是为了替代如下旧模块及函数:os.system、os.spawn*、os.popen*、popen2.*、commands.*。
强烈建议POSIX用户(Linux、BSD等)安装并使用较新的subprocess32模块,而不是Python 2.7自带的subprocess。
快捷函数
推荐用户使用run(新),call、check_call和check_output这三个快捷函数,在无法满足需求的时候才使用更高级的Popen函数。
call、check_call和check_output其实都是调用的Popen函数
run
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, encoding=None, errors=None)
功能:执行args参数所表示的命令,等待命令结束,并返回一个CompletedProcess类型对象。
下面是run参数的作用:
args:表示要执行的命令。必须是一个字符串,字符串参数列表。
stdin、stdout和stderr:子进程的标准输入、输出和错误。其值可以是subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者None。subprocess.PIPE表示为子进程创建新的管道。subprocess.DEVNULL表示使用os.devnull。默认使用的是None,表示什么都不做。另外,stderr可以合并到stdout里一起输出。
timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出TimeoutExpired异常。
check:如果该参数设置为True,并且进程退出状态码不是0,则弹出CalledProcessError异常。
encoding:如果指定了该参数,则stdin、stdout和stderr可以接收字符串数据,并以该编码方式编码。否则只接收bytes类型的数据。
shell:如果该参数为True,将通过操作系统的shell执行指定的命令,如果执行命令时遇见权限不足的境况,可以将此参数设置为True
更多参见:
https://www.cnblogs.com/liangxiyang/p/12124738.html
Popen
获取实时打印
popen = subprocess.Popen("./annie "+url, stdout = subprocess.PIPE,shell=True)# ,bufsize=1
while True:
line = popen.stdout.readline().decode("utf-8")
if not line:
break
call
subprocess.call(args, *, stdin= None, stdout = None, stderr = None, shell = False)
运行由args参数提供的命令,
- args参数是shell命令时,需要提供shell=True参数(否则命令错误时会抛出异常,不会正常返回命令提示)
- 父进程等待子进程完成
- 执行结束并返回返回码,正确执行返回0,否则返回1
- 执行错误不会抛出异常
#coding=utf-8
import subprocess
res = subprocess.call('java -version',shell=True)
print('=====结果:\n', res)
或者
#coding=utf-8
import subprocess
res = subprocess.call(['java','-version'],shell=True)
print('=====结果:\n', res)
注意不要为stdout和stderr参数赋值subprocess.PIPE,如果子进程输出量较多会造成死锁,这两个参数可以赋值为subprocess.STDOUT打印到屏幕或者赋值为一个文件对象将输出写入文件:
网上粘贴的,没试过
#coding=utf-8
import subprocess as sp
sp.call('python run.py', shell = True, stdin=open('fake_input', 'r'), stdout=open('result', 'w'))
check_call
subprocess.check_call(args, *, stdin = None, stdout = None, stderr = None, shell = False)
- 父进程等待子进程完成
- 与call方法类似,不同在于如果命令行执行成功,check_call返回返回码0,否则抛出subprocess.CalledProcessError异常。
- subprocess.CalledProcessError异常包括returncode、cmd、output等属性,其中returncode是子进程的退出码,cmd是子进程的执行命令,output为None。
可用try…except…检查
#coding=utf-8
import subprocess
#必须加上shell=True,否则命令错误时会抛出异常,会不正常返回命令提示
try:
res = subprocess.check_call(['java2','-version'],shell=True)
print('=====结果:\n', res)
except subprocess.CalledProcessError, exc:
print('\n异常信息:')
print('returncode:', exc.returncode)
print('cmd:', exc.cmd)
print('output:', exc.output)
注意:不要为stdout和stderr参数赋值为subprocess.PIPE。
check_output
subprocess.check_output(args, *, stdin = None, stderr = None, shell = False, universal_newlines = False)
- 父进程等待子进程完成
- 以字符串形式返回执行结果的输出(即返回子进程向标准输出的输出结果),必须指定stderr = subprocess.STDOUT,否则返回为空
- 检查退出信息,如果returncode不为0,则抛出subprocess.CalledProcessError异常,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try…except…来检查。
#coding=utf-8
import subprocess
try:
res = subprocess.check_output('java2 -version',
stderr = subprocess.STDOUT,
shell = True)
print ('结果:\n', res)
except subprocess.CalledProcessError, exc:
print ('returncode:', exc.returncode)
print ('cmd:', exc.cmd)
print ('output:', exc.output)
执行ping baidu.com -t就废废了,有-t,会一直执行,执行不结束,就不会输出内容
注意:不要为stderr参数赋值为subprocess.PIPE。
更简单的文章参看:
http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html
感谢以下文章
http://blog.csdn.net/a464057216/article/details/47355219
http://www.jb51.net/article/48086.htm