Subprocess模块
python3.5将使用Subprocess模块跟操作系统进行交互,比如系统命令,他将替换
os.system
os.spawn*
subprocess.run()方法封装的subprocess.Popen()
subprocess.run()方法只在3.5中才有2.7中有一个subprocess.call()方法
>>> subprocess.call(['df','-lh'])
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk1 465Gi 209Gi 256Gi 45% 54730457 67109157 45% /
/dev/disk2s1 741Mi 557Mi 184Mi 76% 142675 47036 75% /Volumes/Parallels Desktop 11
/dev/disk3s2 786Mi 669Mi 117Mi 86% 171353 29853 85% /Volumes/ParallelsDesktop 11.1.3-32521
这里给call方法,传“df -lh”这种多个参数时,用的是传入列表的形式['df','-lh’],python解释器在处理subprocess.call()方法时,将传进来的列表参数经过处理,最终转换成shell中的df -lh,那么如果我就不想传列表,怎么办呢。2.7中也可以实现,如下方法
>>> subprocess.call('df -lh',shell=True)
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk1 465Gi 209Gi 256Gi 45% 54730303 67109311 45% /
/dev/disk2s1 741Mi 557Mi 184Mi 76% 142675 47036 75% /Volumes/Parallels Desktop 11
/dev/disk3s2 786Mi 669Mi 117Mi 86% 171353 29853 85% /Volumes/ParallelsDesktop 11.1.3-32521
这里 subprocess.call('df -lh',shell=True)就明确告诉python解释器,你不用给我转了,就使用shell来进行执行。
很多时候,我门都想通过python里的模块方法获得执行结果。
怎么实现呢。
>>> a = subprocess.call("df -lh",shell=True)
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk1 465Gi 209Gi 256Gi 45% 54730696 67108918 45% /
/dev/disk2s1 741Mi 557Mi 184Mi 76% 142675 47036 75% /Volumes/Parallels Desktop 11
/dev/disk3s2 786Mi 669Mi 117Mi 86% 171353 29853 85% /Volumes/ParallelsDesktop 11.1.3-32521
>>> a
这里我们看到0为执行命令的返回状态。
那么怎么得到结果呢。通过管道。将结果通过管道返回。
>>> a = subprocess.call("df -lh",shell=True,stdout=subprocess.PIPE)
>>> a
我们得到依然是0,为毛。因为call方法只返回执行状态。不返回命令执行结果。
如果想存下来,不能用call,要用Popen方法。
>>> a = subprocess.Popen('df -lh',shell=True)
>>> Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/disk1 465Gi 209Gi 256Gi 45% 54852887 66986727 45% /
/dev/disk2s1 741Mi 557Mi 184Mi 76% 142675 47036 75% /Volumes/Parallels Desktop 11
/dev/disk3s2 786Mi 669Mi 117Mi 86% 171353 29853 85% /Volumes/ParallelsDesktop 11.1.3-32521
>>> a
<subprocess.Popen object at 0x10881cb50>
看到这个和os模块的Popen方法得到的一样。那么我们试下a.read()
发现没有read()方法。在试下a.stdout.read()
同样没有a.stdout.read()方法。
那么分析下python运行Popen方法的执行过程。
Popen()方法执行里面的shell命令,其实是python又开启了一个子进程,子进程运行的结果要想返回给Popen()方法,需要使用管道,写法如下:
>> a = subprocess.Popen('df -lh',shell=True,stdout=subprocess.PIPE)
>>> a.returncode
a.returncode
>>> a.std
a.stderr a.stdin a.stdout
>>> a.stdout.read()
'Filesystem Size Used Avail Capacity iused ifree %iused Mounted on\n/dev/disk1 465Gi 209Gi 255Gi 46% 54971946 66867668 45% /\n/dev/disk2s1 741Mi 557Mi 184Mi 76% 142675 47036 75% /Volumes/Parallels Desktop 11\n/dev/disk3s2 786Mi 669Mi 117Mi 86% 171353 29853 85% /Volumes/ParallelsDesktop 11.1.3-32521\n’
总结:
使用subprocess模块,想获得命令执行结果。1.使用Popen方法 2.使用管道3.使用a.stdout.read()方法记住下面的例子即可:
a = subprocess.Popen('df -lh',shell=True,stdout=subprocess.PIPE)
subprocess 另外几个方法
subprocess.check_call()检查执行结果,如果返回0说明执行正常,如果不返回0,返回报错
>>> subprocess.call('sssdf',shell=True)
/bin/sh: sssdf: command not found
127
>>> subprocess.check_call('sssdf',shell=True)
/bin/sh: sssdf: command not found
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 540, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'sssdf' returned non-zero exit status 127
>>>
subprocess.check_stdout()
subprocess.Popen()的其他参数,记住下面三个即可。其他用的少
stdin,stdout,stderr:分别表示程序的标准输入、输出、错误句柄
举例:
>>> obj = subprocess.Popen(["python"],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
>>> obj.stdin.write('print 1 \n')
>>> obj.stdin.write('print 2 \n')
>>> obj.stdin.write('print 3 \n')
>>> obj.stdin.write('print 4 \n’)
执行到这里,我想执行前面的输入内容了,那么就要用communicate() 方法
>>> out_error_list = obj.communicate()
>>> print out_error_list
('1\n2\n3\n4\n', ‘')
python2.7是这样写,python3.5就不用Popen,想得到命令的执行结果用subporcess.run()方法即可,run方法在2.7中是没有的
>>> b = subprocess.run('df -lh',shell=True,stdout=subprocess.PIPE)
>>> b
CompletedProcess(args='df -lh', returncode=0, stdout=b'Filesystem Size Used Avail Capacity iused ifree %iused Mounted on\n/dev/disk1 465Gi 210Gi 255Gi 46% 54985500 66854114 45% /\n/dev/disk2s1 741Mi 557Mi 184Mi 76% 142675 47036 75% /Volumes/Parallels Desktop 11\n/dev/disk3s2 786Mi 669Mi 117Mi 86% 171353 29853 85% /Volumes/ParallelsDesktop 11.1.3-32521\n')
>>>