subprocess-About-简介
subprocess
模块用来创建新的进程,连接到其stdin、stdout、stderr管道并获取它们的返回码。
subprocess模块的出现是为了替代旧模块及函数:os.system
、os.spawn*
、os.popen*
、popen2.*
、commands.*
。
强烈建议POSIX用户(Linux、BSD等)安装并使用较新的subprocess32
模块,而不是Python 2.7自带的subprocess。
推荐用户使用call
、check_call
和check_output
这三个快捷函数,在无法满足需求的时候才使用更高级的Popen
接口。
subprocess.call-调用
call函数可以认为是对popen
和wait
的分装,直接对call
函数传入要执行的命令行,将命令行的退出code返回。
运行由args
参数提供的命令,等待命令执行结束并返回返回码。args参数由字符串形式提供且有多个命令参数时,
需要提供shell=True
参数:
1
| subprocess.call(args, *, stdin= None, stdout = None, stderr = None, shell = False)
|
注意不要为stdout和stderr参数赋值subprocess.PIPE,如果子进程输出量较多会造成死锁,这两个参数可以赋值为subprocess.STDOUT打印到屏幕或者赋值为一个文件对象将输出写入文件:
1 2 3
| //test.py-示例 import subprocess as sp sp.call('python run.py', shell = True, stdin=open('fake_input', 'r'), stdout=open('result', 'w'))
|
subprocess.check_call-调用返回确认
与call方法类似,不同在于如果命令行执行成功,check_call
返回返回码0,否则抛出subprocess.CalledProcessError异常。
1
| subprocess.check_call(args, *, stdin = None, stdout = None, stderr = None, shell = False)
|
subprocess.check_output-调用输出确认
在子进程执行命令,以字符串形式返回执行结果的输出。如果子进程退出码不是0,抛出subprocess.CalledProcessError异常,异常的output字段包含错误输出:
1
| subprocess.check_output(args, *, stdin = None, stderr = None, shell = False, universal_newlines = False)
|
subprocess.Popen 管道调用
开启新进程
Popen启动新的进程与父进程并行执行,默认父进程不等待新进程结束。
1 2 3 4 5
| def TestPopen(): import subprocess p=subprocess.Popen("dir",shell=True) for i in range(250) : print ("other things")
|
等待子进程结束
p.wait
函数使得父进程等待新创建的进程运行结束,然后再继续父进程的其他任务。且此时可以在p.returncode
中得到新进程的返回值。
1 2 3 4 5 6 7 8
| def TestWait(): import subprocess import datetime print (datetime.datetime.now()) p=subprocess.Popen("sleep 10",shell=True) p.wait() print (p.returncode) print (datetime.datetime.now())
|
poll等待
p.poll
函数可以用来检测新创建的进程是否结束。
1 2 3 4 5 6 7 8 9 10 11 12 13
| def TestPoll(): import subprocess import datetime import time print (datetime.datetime.now()) p=subprocess.Popen("sleep 10",shell=True) t = 1 while(t <= 5): time.sleep(1) p.poll() print (p.returncode) t+=1 print (datetime.datetime.now())
|
结束进程
p.kill
或p.terminate
用来结束创建的新进程,在windows系统上相当于调用TerminateProcess()
,在posix系统上相当于发送信号SIGTERM和SIGKILL。
1 2 3 4 5 6 7 8 9 10
| def TestKillAndTerminate(): p=subprocess.Popen("notepad.exe") t = 1 while(t <= 5): time.sleep(1) t +=1 p.kill() print ("new process was killed")
|
与子进程交互
p.communicate
可以与新进程交互,但是必须要在popen构造时候将管道重定向。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| def TestCommunicate(): import subprocess cmd = "dir" p=subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (stdoutdata, stderrdata) = p.communicate() if p.returncode != 0: print (cmd + "error !") for r in str(stdoutdata,encoding='utf8' ).split("\n"): print (r) print (p.returncode) def TestCommunicate2(): import subprocess cmd = "dir" p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) curline = p.stdout.readline() while(curline != ""): print (curline) curline = p.stdout.readline() p.wait() print (p.returncode)
|