zoukankan      html  css  js  c++  java
  • 子进程管理模块subprocess

            subprocess模块允许你生成子进程,连接管道,并获取返回的代码。

            一.使用subprocess模块

            模块中定义了一个Popen类:

            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:应该是一个字符串,或者一连串命令参数,要运行的程序通常是是args的第一个元素,但是也可以通过executable来显示声明。如果显示声明了args,参数序列的第一个元素依然被大多数程序作为命令名。

    1. >>>import shlex, subprocess
    2. >>> command_line = raw_input()
    3. /bin/vikings -input eggs.txt -output "spam spam.txt"-cmd "echo '$MONEY'"
    4. >>> args = shlex.split(command_line)
    5. >>>print args
    6. ['/bin/vikings','-input','eggs.txt','-output','spam spam.txt','-cmd',"echo '$MONEY'"]
    7. >>> p = subprocess.Popen(args)# Success!

            在Unix中,如果shell=false(默认情况下),那么Popen使用os.execvp()来执行子程序,args应该是参数序列。如果shell=true,如果args是字符串,那么这个字符串必须跟在命令行中输入的字符串一样;如果是参数序列,第一个元素指定为命令行字符串,剩下的元素就被视为参数,也就是说,相当于以下的命令。

    1. Popen(['/bin/sh','-c', args[0], args[1],...])

            而在Window中,Popen使用CreateProcess()来执行子程序,传递的args为字符串,如果arg是参数序列,将会自动调用list2cmdline()转化成字符串。

            bufsize:0意味着无缓存(默认值),1意味着行缓存,其他正整数意味着使用这个整数大小作为缓存大小。负整数意味着使用系统默认的值,通常意味着全缓存。

            executable:指定要执行的程序,一般不需要。

            stdin、stdout、stderr:指定程序的标准输出,标准输入,标准错误输出。可能值为管道或者文件描述符,文件对象,或者None。stderr可以为STDOUT,意思是错误信息页通过标准输出输出。

            preexec_fn:可调用对象,在程序执行前调用,只有Unix下可用。

            close_fds:如果为True,所有的文件描述符(除了0,1,2)在子进程运行前都得关闭。(只有Unix下可用)。

            shell:如果为True,指定的命令将通过shell来执行。

            cwd:如果不是None,那么子进程当前的目录在执行前会切换到cwd,注意当搜索可执行文件的时候不是根据这个目录来查找的,所以不能针对这个目录来指定相对路径。

            env:如果非None,必须是一个映射,定义了针对这个子进程的环境变量。

            univerval_newline:如果为True,则所有平台使用通用的换行符' '。

            startupinfo、creationflag:仅针对windows有效。

            subprocess.PIPE:可以传递给stdin、stdout、stderr的特殊值。

            subprocess.STDOUT可以传递给stderr,表示错误信息通过stdout输出。

            1.实用方法

            模块提供了两个实用方法。

            subprocess.call(*popenargs, **kwargs)

            使用给定参数运行命令,等待命令执行完,然后返回返回码。给定的参数跟Popen的参数一样。例如  

    1. >>> retcode = subprocess.call(["ls","-l"])

            subprocess.check_call(*popenargs, **kwargs)

            使用给定参数运行命令,等待命令执行完,如果返回码为0,则返回它,如果非0,则将抛出CalledProcessError,这个对象里面有returncode属性。需要的参数跟Popen的一样。例如 

    1. >>> subprocess.check_call(["ls","-l"])
    2. 0
            subprocess.check_output(*popenargs, **kwargs)
            运行命令并返回结果,结果为字符串形式。如果返回码非0,将抛出CalledProcessError异常,需要的参数跟Popen一样。
    1. >>> subprocess.check_output(["ls","-l","/dev/null"])
    2. 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null '
            如果想捕获异常信息,可以使用stderr=subprocess.STDOUT。
    1. >>> subprocess.check_output(
    2. ...["/bin/sh","-c","ls non_existent_file; exit 0"],
    3. ... stderr=subprocess.STDOUT)
    4. 'ls: non_existent_file: No such file or directory '

            2.异常

            异常在子进程中抛出,异常还有一个格外的属性,child_traceback。最常见的异常是OSError。例如执行一个不存在的文件。当Popen使用一个非法的参数时,抛出ValueError异常,check_output()会抛出CalledProcessError。

            二、Popen对象

            Popen对象有如下方法。

            Popen.poll() :检查子进程是否被中断,设置并返回返回码。

            Popen.wait():等待子程序运行完,设置并返回返回码。

            Popen.communicate(input=None):与子进程进行通信。输入信息到stdin,从stdout和stderr中读取信息。知道文件末尾。等待进程执行完,可选参数是个字符串,是输入给子进程的信息,如果为None,则意味着不需要发送信息给子进程。这个方法返回一个元组(stdoutdata, stderrdata),注意,如果你想发送信息给子进程,必须在创建Popen的时候使用stdin=PIPE,同样,如果想从stdout和stderr中获取信息,也需要设置它们为PIPE。

            Popen.send_signal(signal):给子进程发送信号。

            Popen.terminate():终止子进程

            Popen.kill():杀死子进程。

            Popen.stdin:子进程的标准输入

            Popen.stdout:子进程的标准输出。

            Popen.stderr:子进程的标准错误输出。

            Popen.pid:子进程的ID。

            Popen.returncode:子进程的返回码

            三、示例。

            通过subprocess,可以在python中间接的执行shell命令。以下例子均假设已经运行了from subprocess import * 命令。

            例1:间接执行反引号语句

    1. output=`mycmd myarg`
    2. ==>
    3. output =Popen(["mycmd","myarg"], stdout=PIPE).communicate()[0]
            例2:间接执行shell管道命令
    1. output=`dmesg | grep hda`
    2. ==>
    3. p1 =Popen(["dmesg"], stdout=PIPE)
    4. p2 =Popen(["grep","hda"], stdin=p1.stdout, stdout=PIPE)
    5. output = p2.communicate()[0]
            例3:间接执行os.system()
    1. sts = os.system("mycmd"+" myarg")
    2. ==>
    3. p =Popen("mycmd"+" myarg", shell=True)
    4. sts = os.waitpid(p.pid,0)[1]
            通过通过返回码判断命令是否运行成功。
    1. try:
    2. retcode = call("mycmd"+" myarg", shell=True)
    3. if retcode <0:
    4. print>>sys.stderr,"Child was terminated by signal",-retcode
    5. else:
    6. print>>sys.stderr,"Child returned", retcode
    7. exceptOSError, e:
    8. print>>sys.stderr,"Execution failed:", e
            





  • 相关阅读:
    mysql 存储过程实例
    国际会议查询方式和相关会议
    用 WEKA 进行数据挖掘,第 1 部分: 简介和回归(转)
    java实现甘特图的2种方法:SwiftGantt和Jfree (转)
    通过jxl 读取excel 文件中的日期,并计算时间间隔
    R 操作矩阵和计算SVD的基本操作记录
    SVD java 算法实现
    聚类方法简介
    Kolmogorov-Smirnov检验
    Java Thread 多线程 介绍
  • 原文地址:https://www.cnblogs.com/fireflow/p/4841432.html
Copyright © 2011-2022 走看看