zoukankan      html  css  js  c++  java
  • Python之子进程subprocess模块

    http://www.cnblogs.com/vamei/archive/2012/09/23/2698014.html

    http://blog.csdn.net/jgood/article/details/4498166

    http://docs.python.org/library/subprocess

    subprocess.call()

    [root@typhoeus79 20130925]# more test.py 
    #!/usr/bin/env python2.7
    #-*- coding:utf8 -*-
    
    import subprocess
    
    rc = subprocess.call(["ls","-l"])
    
    print "rc = ",rc
    [root@typhoeus79 20130925]# ./test.py    
    total 4
    -rwxr-xr-x 1 root root 118 Sep 25 11:18 test.py
    rc =  0

    将程序名ls和其对应的参数放在一个list中传给subprocess.call()

    通过一个shell来解释字符串

    [root@typhoeus79 20130925]# ./sub_shell.py 
    total 4
    -rwxr-xr-x 1 root root 125 Sep 25 11:22 sub_shell.py
    rc =  0
    [root@typhoeus79 20130925]# more sub_shell.py 
    #!/usr/bin/env python2.7
    #-*- coding:utf8 -*-
    
    import subprocess
    
    rc = subprocess.call("ls -l",shell=True)
    
    print "rc = ",rc

    使用shell=True这个参数,使用字符串而不是使用list来运行子进程。python先运行一个shell,然后这个shell来解释整个字符串

     

    Popen

    基于Popen()的封装(wrapper),这些封装的目的在于让我们容易使用子进程。当我们想要更个性化我们的需求的时候,就要转向Popen类,该类生成的对象用来代表子进程

        Using the subprocess module
        ===========================
        This module defines one class called Popen:
        
        class 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):
    [root@typhoeus79 20130925]# ./sub_popen.py   
    parent process
    <subprocess.Popen object at 0x7fed17542050>
    [root@typhoeus79 20130925]# PING www.a.shifen.com (220.181.111.148) 56(84) bytes of data.
    
    --- www.a.shifen.com ping statistics ---
    5 packets transmitted, 0 received, 100% packet loss, time 4002ms
    
    
    [root@typhoeus79 20130925]# more sub_popen.py 
    #!/usr/bin/env python26
    #-*- coding:utf8 -*-
    
    import subprocess
    
    child = subprocess.Popen(["ping","-c","5","www.baidu.com"])
    #child = subprocess.Popen("ping -c5 www.baidu.com",shell=True)
    
    print("parent process")
    print child

    父进程在开启子进程之后没有等到其完成,而是直接print

    改成等待模式:

    [root@typhoeus79 20130925]# ./sub_popen.py    
    PING www.a.shifen.com (220.181.112.143) 56(84) bytes of data.
    
    --- www.a.shifen.com ping statistics ---
    5 packets transmitted, 0 received, 100% packet loss, time 4001ms
    
    parent process
    <subprocess.Popen object at 0x7fe424c34050>
    [root@typhoeus79 20130925]# more sub_popen.py 
    #!/usr/bin/env python26
    #-*- coding:utf8 -*-
    
    import subprocess
    
    child = subprocess.Popen(["ping","-c","5","www.baidu.com"])
    
    child.wait()
    print("parent process")
    print child

    父进程中对子进程进行其他操作:

    child.poll() #检查子进程状态

    child.kill() #终止子进程

    child.send_signal() #向子进程发送信号

    child.terminate() #终止子进程

    子进程的PID存储在child.pid中

    子进程的文本流控制

    子进程的标准输入、标准输出、标准错误通过如下属性:

    {'_child_created': True, 'returncode': 1, 'stdout': None, 'stdin': None, 'pid': 7070, 'stderr': None, 'universal_newlines': False}

    child.stdin

    child.stdout

    child.stderr

    可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出在一起,构成管道pipe:

    [root@typhoeus79 20130925]# more sub_pipe.py 
    #!/usr/bin/env python26
    #-*- coding:utf8 -*-
    
    import subprocess
    
    child1 = subprocess.Popen(["ls","-l"],stdout=subprocess.PIPE)
    
    child2 = subprocess.Popen(["wc"],stdin=child1.stdout,stdout=sub
    process.PIPE)
    
    out = child2.communicate()
    
    print out
    [root@typhoeus79 20130925]# ./sub_pipe.py    
    ('      4      29     167
    ', None)

    1、child1的stdout将文本输出缓存到subprocess.PIPE中

    2、child2的stdin从child1的stdout读取文本

    3、child2的输出文本也被存储在subprocess.PIPE中

    4、communicate()方法从PIPE中读取相应的文本

    communicate是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。

        communicate(input=None)
            Interact with process: Send data to stdin.  Read data from stdout
            and stderr, until end-of-file is reached.  Wait for process to
            terminate.  The optional input argument should be a string to be
            sent to the child process, or None, if no data should be sent to
            the child.
        
            communicate() returns a tuple (stdout, stderr).
        
            Note: The data read is buffered in memory, so do not use this
            method if the data size is large or unlimited.

    可以使用communicate()方法使用PIPE给子进程输入:

    #!/usr/bin/env python26
    #-*- coding:utf8 -*-
    
    import subprocess
    import time
    
    child = subprocess.Popen(["cat"],stdin=subprocess.PIPE)
    
    time.sleep(5)
    child.communicate("Hello
    ")

    通过time.sleep也可以看到communicate是阻塞父进程

    对python执行系统命令的封装

    def sys_command(system_cmd):
            logger.debug("system_cmd = '%s'." %system_cmd)
            pipe = subprocess.Popen(system_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True,stdin=subprocess.PIPE)
    
            stdout, stderr = pipe.communicate()
            returncode = pipe.returncode
    
            logger.debug("returncode = '%d'." %returncode)
            logger.debug("stdout = '%s'." %stdout)
            logger.debug("stderr = '%s'." %stderr)
    
            return returncode,stdout,stderr
  • 相关阅读:
    git merge
    google platform
    http tutorial
    DS,AA tree
    Java,Hashtable
    java,Object
    Pumping lemma for regular languages
    Pumping lemma
    Context-free grammar
    Formal language
  • 原文地址:https://www.cnblogs.com/gsblog/p/3338337.html
Copyright © 2011-2022 走看看