Python subprocess 模块

喜欢一个人那么久,那个人就和自己的过去捆在一起了,要是后悔以前喜欢过谁,不就是把自己以前的时间都否定了么?

Subprocess模块主要是用来在Python中执行cmd命令或shell命令,通过自己带程序调用系统命令,在os模块中有使用os.system()和os.popen().read()方法,但是这两种方法基本上被舍弃了,所以学习subprocess还是很有必要的,如果只是简单的执行命令的话哪种方便就使用哪种,不要本末倒置了。

主要的使用方法

1. subprocess.run()    
Python 3.5中新增的函数。执行指定的命令,等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。
2. subprocess.call()
执行指定的命令,返回命令执行状态,其功能类似于os.system(cmd)。
3. subprocess.check_call()
Python 2.5中新增的函数。 执行指定的命令,如果执行成功则返回状态码,否则抛出异常。其功能等价于subprocess.run(...,check=True)。
4.subprocess.check_output()    
Python 2.7中新增的的函数。执行指定的命令,如果执行状态码为0则返回命令执行结果,否则抛出异常。
5.subprocess.getoutput(cmd)    
接收字符串格式的命令,执行命令并返回执行结果,其功能类似于os.popen(cmd).read()
6.subprocess.getstatusoutput(cmd)    
执行cmd命令,返回一个元组(命令执行状态, 命令执行结果输出)

#subprocess.Popen类的实例可调用的方法

使用格式

subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, 
preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False,
startup_info=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=())

参数说明:

1.args:
 要执行的shell命令,可以是字符串,也可以是命令各个参数组成的序列。当该参数的值是一个字符串时,该命令的解释过程是与平台相关的,因此通常建议将args参数作为一个序列传递。
2.bufsize: 
指定缓存策略,0表示不缓冲,1表示行缓冲,其他大于1的数字表示缓冲区大小,负数 表示使用系统默认缓冲策略。
3.stdin, stdout, stderr: 
分别表示程序标准输入、输出、错误句柄。
4.preexec_fn: 
用于指定一个将在子进程运行之前被调用的可执行对象,只在Unix平台下有效。
5.close_fds: 
如果该参数的值为True,则除了0,1和2之外的所有文件描述符都将会在子进程执行之前被关闭。
6.shell: 
该参数用于标识是否使用shell作为要执行的程序,如果shell值为True,则建议将args参数作为一个字符串传递而不要作为一个序列传递。
7.cwd: 
如果该参数值不是None,则该函数将会在执行这个子进程之前改变当前工作目录。
8.env: 
用于指定子进程的环境变量,如果env=None,那么子进程的环境变量将从父进程中继承。如果env!=None,它的值必须是一个映射对象。
9.universal_newlines: 
如果该参数值为True,则该文件对象的stdin,stdout和stderr将会作为文本流被打开,否则他们将会被作为二进制流被打开。
10.startupinfo和creationflags: 
这两个参数只在Windows下有效,它们将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如主窗口的外观,进程优先级等。

Popen的常用方法

1.Popen.poll()    
用于检查子进程(命令)是否已经执行结束,没结束返回None,结束后返回状态码。
2.Popen.wait(timeout=None)    
等待子进程结束,并返回状态码;如果在timeout指定的秒数之后进程还没有结束,将会抛出一个TimeoutExpired异常。
3.Popen.communicate(input=None, timeout=None)    
该方法可用来与进程进行交互,比如发送数据到stdin,从stdout和stderr读取数据,直到到达文件末尾。
4.Popen.send_signal(signal)    
发送指定的信号给这个子进程。
5.Popen.terminate()    
停止该子进程。
6.Popen.kill()    
杀死该子进程。

实测最有用的用法

comm = 'dir'
res = subprocess.Popen(comm, shell=True, stdout=subprocess.PIPE)
result = res.stdout.read().decode()
print(result)
res.terminate()

总结

  1. 首先应该知道的是,Python2.4版本引入了subprocess模块用来替换os.system()、os.popen()、os.spawn*()等函数以及commands模块;也就是说如果你使用的是Python 2.4及以上的版本就应该使用subprocess模块了。
  2. 如果你的应用使用的Python 2.4以上,但是是Python 3.5以下的版本,Python官方给出的建议是使用subprocess.call()函数。Python 2.5中新增了一个subprocess.check_call()函数,Python 2.7中新增了一个subprocess.check_output()函数,这两个函数也可以按照需求进行使用。
  3. 如果你的应用使用的是Python 3.5及以上的版本(目前应该还很少),Python官方给出的建议是尽量使用subprocess.run()函数。
  4. 当subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()这些高级函数无法满足需求时,我们可以使用subprocess.Popen类来实现我们需要的复杂功能。
坚持原创技术分享,您的支持将鼓励我继续创作!
------ 本文结束 ------

版权声明

LangZi_Blog's by Jy Xie is licensed under a Creative Commons BY-NC-ND 4.0 International License
由浪子LangZi创作并维护的Langzi_Blog's博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于Langzi_Blog's 博客( http://langzi.fun ),版权所有,侵权必究。

0%