@hainingwyx
2018-09-02T16:22:37.000000Z
字数 2264
阅读 1807
Python
subprocess包主要功能是执行外部的命令和程序。比如说,我需要使用wget下载文件。我在Python中调用wget程序。从这个意义上来说,subprocess的功能与shell类似。
subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。
subprocess.call()
:父进程等待子进程完成,返回退出信息
subprocess.check_call()
:父进程等待子进程完成,返回0,检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try...except...来检查
subprocess.check_output()
:父进程等待子进程完成,返回子进程向标准输出的输出结果。检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try...except...来检查。
举例说明:
import subprocess
out = subprocess.call("ls -l", shell=True)
out = subprocess.call("cd ..", shell=True)
上面的三个函数都是基于Popen()的封装(wrapper)。这些封装的目的在于让我们容易使用子进程。当我们想要更个性化我们的需求的时候,就要转向Popen类,该类生成的对象用来代表子进程。
属性:
p.pid
:子进程的PID
p.returncode
:子进程的返回状态,即None —— 子进程尚未结束;==0 ——子进程正常退出;> 0—— 子进程异常退出,returncode对应于出错码;< 0—— 子进程被信号杀掉了。
p.stdin
, p.stdout
, p.stderr
:子进程对应的一些初始文件,如果调用Popen()的时候对应的参数是subprocess.PIPE,则这里对应的属性是一个包裹了这个管道的 file 对象,
方法:
p.poll()
:检查子进程 p 是否已经终止,返回 p.returncode 属性
p.wait()
:
Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block):
import subprocess
child = subprocess.Popen(["ping","-c","5","www.google.com"])
print("parent process")
对比等待的情况:
import subprocess
child = subprocess.Popen(["ping","-c","5","www.google.com"])
child.wait()
print("parent process")
此外,还可以在父进程中对子进程进行其它操作:
child.poll() # 检查子进程状态
child.kill() # 终止子进程
child.send_signal() # 向子进程发送信号
child.terminate() # 终止子进程
子进程的标准输入,标准输出和标准错误也可以通过如下属性表示:
、
child.stdinchild.stdout
、child.stderr
可在Popen()建立子进程时改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe):
import subprocess
child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE)
out = child2.communicate()
print(out)
subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
要注意的是,communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。
还可利用communicate()方法来使用PIPE给子进程输入:
import subprocess
child = subprocess.Popen(["cat"], stdin=subprocess.PIPE)
child.communicate("test")
我们启动子进程之后,cat会等待输入,直到我们用communicate()输入"test"。
http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html
https://www.cnblogs.com/Security-Darren/p/4733368.html