subprocess模块用来管理子进程,可以调用外部的命令作为子进程,而且可以连接到子进程的input/output/error管道,获取相关的返回信息。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
常用方法
-
subprocess.call()
父进程等待子进程完成,执行命令,返回执行状态,不能获取到命令输出的内容,当shell为True时,第一个参数可以直接输入命令,如果为False,则必须用列表来输入
1 import subprocess 2 3 ret=subprocess.call("ipconfig",shell=True) 4 ret2=subprocess.call(["ls", "-al"],shell=False) 5 6 print(ret)
-
subprocess.check_call()
父进程等待子进程完成,执行命令,不能获取到命令输出的内容,如果执行状态码是 0 ,则返回0,否则抛异常,当shell为True时,第一个参数可以直接输入命令,如果为False,则必须用列表来输入
1 import subprocess 2 3 ret=subprocess.check_call("ifconfig",shell=True) 4 ret2=subprocess.check_call(["ls", "-al"],shell=False) 5 6 print("*************") 7 print(ret , ret2)
- subprocess.check_output()
父进程等待子进程完成,执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
import subprocess ret=subprocess.check_output("ipconfig",shell=True) print("*************") #check_output返回的是字节,转化了字符串输出 retStr=str(ret,encoding="gbk") print(retStr)
- subprocess.Popen(...)
上面的call,check_call,check_output这三个函数都是Popen的封装,为了更好的使用子进程,如果需求更个性话只需要使用Popen,和上面三个不同的 是,Popen创建的对象后,主程序不会等待子进程完成,必须调用对象的wait()函数才会等待
参数:
1 args shell命令,可以是字符串或者序列类型(如:list,元组) 2 bufsize 指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲 3 stdin, stdout, stderr 分别表示程序的标准输入、输出、错误句柄 4 preexec_fn 只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用 5 close_sfs 在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。 6 所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。 7 shell 当shell为True时,第一个参数可以直接输入命令,如果为False,则必须用列表来输入 8 cwd 用于设置子进程的当前目录 9 env 用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。 10 universal_newlines 不同系统的换行符不同,True -> 同意使用 \n 11 startupinfo与createionflags只在windows下有效 12 将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
对创建的子进程进行其它操作
-
- 对象.poll() 检查子进程的状态
- 对象.kill() 终止子进程
- 对象.send_signal() 向子进程发送信号
- 对象.terminate() 终止子进程
对子进程的文本控制
-
- stdin
- stdout
- stderr
1 import subprocess 2 3 ret=subprocess.Popen("python",stdin=subprocess.PIPE, 4 stdout=subprocess.PIPE, 5 stderr=subprocess.PIPE, 6 universal_newlines=True) 7 ret.stdin.write("print(1)\n") 8 ret.stdin.write("print(11)\n") 9 ret.stdin.close() 10 11 print(ret.stdout.read()) 12 ret.stdout.close() 13 print("***************") 14 print(ret.stderr.read()) 15 ret.stderr.close() 16 17 ###########结果############## 18 1 19 11 20 21 ***************
1 import subprocess 2 3 ret=subprocess.Popen("python",stdin=subprocess.PIPE, 4 stdout=subprocess.PIPE, 5 stderr=subprocess.PIPE, 6 universal_newlines=True) 7 ret.stdin.write("print(1)\n") 8 ret.stdin.write("print(11)\n") 9 ret.stdin.close() 10 #communicate会将stdout和stderr的内容放在一个元祖中 11 out_error_list = ret.communicate() 12 print(out_error_list) 13 14 ###########结果############ 15 (‘1\n11\n‘, ‘‘)