继续介绍subprocess模块里的Popen类。Popen类很强大,提供了很多参数和方法来管理子进程。其中很多数参数我并没有亲自使用过。所以这部分更多只是当官方文档的搬运工。
class subprocess.
Popen
(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)
args, stdin, stdout, stderr 和shell与之前三个函数的用法一样。在前篇讲过当stderr=PIPE时建议使用Popen.communicate()方法,在介绍wait()方法时会说明原因,其他的这里不在重复。
bufsize: 缓存大小,0表示没有缓存,正数表示缓存大小,负数表示使用系统默认大小。
executable: 当shell=False时,替代args里的命令,但是args里的值仍旧会传个executable指定的程序。当shell=True,则会启动executable指定的shell代替系统默认的来运行args。(在windows中,我试着运行Popen("print a", shell=True, executable='c:\\Python27\\python.exe'没有成功。抛出c:\windows\system32\cmd.exe: can not open file '/c' No such file or directory. 不知道什么 原因。有高手的话欢迎指教。回头到linux上试验后再来更新)
preexec_fn: 指定一个可调用的对象,比如函数,它会在子进程开始前执行(unix only)
close_fd: Unix中,在子进程运行前会把除了0,1,2之外的文件描述全部关闭。Windows中,则不会继承父进程的任何文件描述,包括0,1,2.
env: 非none的情况下,会使用env中指定的环境变量,而不会继承父进程的。
startupinfo: STARTUPINFO 类,会传给CreateProcess方法。这个类也在subprocess模块中,用来定义一些参数控制子进程在Windows中的运行。不是很了解具体用法。Windows only。
creationflage: 可以是CREATE_NEW_CONSOLE 或者 CREATE_NEW_PROCESS_GROUP。 CREATE_NEW_CONSOLE表示子进程在新的console中运行而不是继承自父进程。CREATE_NEW_PROCESS_GROUP则是会生成一个新的进程组。Windows Only。
下面是Popen对象一些方法。
Popen.poll(): 检查子进程是否已停止。返回0表示停止,返回none表示没有。这里多说一句,看到一篇帖子是说利用poll()来判断子进程是否停止从而在父进程停止打印输出遇到问题 http://bbs.chinaunix.net/thread-3775926-1-1.html。很有参考性。
Popen.wait(): 等待子进程结束,并返回returncode。 这里需要注意如果使用了stdout=PIPE or stderr=PIPE, 则避免使用这个函数。原因是如果输出超过了PIPE的size后,子进程会停止输出到PIPE。但是父进程必须等到子进程完成后才会继续,所以就造成了死锁。官方建议使用Popen.communicate()。原因是communicate会把stdout,stderr里的数据放到内存中,从而解决了这个问题。这篇文章很好地展示了这个问题 https://blog.csdn.net/carolzhang8406/article/details/22286913
Popen.communicate(input=None): 将input输入给子进程,从stdout和stderr读出数据直到EOF。返回一个元组(stdoutdata, stderrdata)。 这里也要注意一个问题,因为comunicate函数是把数据放到内存中的,如果输出大量或无限制的数据则不应使用这个函数。
Popen.send_signal(signal): 将signal传给子进程,在Windows上基本没用。
Popen.terminate(): 停止子进程。在Posix OSs,这个方法发送SIGTERM到子进程中。 Windows中调用TerminateProcess()
Popen.kill(): 杀掉子进程。 在Posix OSs,发送SIGKILL到子进程。Windows中与Popen.terminate()相同