zoukankan      html  css  js  c++  java
  • python

    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:可以是字符串或者序列类型(如:list,元组),用于指定进程的可执行文件及其参数。

       如果是序列类型,第一个元素通常是可执行文件的路径。我们也可以显式的使用executeable参数来指定可执行文件的路径。

    stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄。他们可以是PIPE,文件描述符或文件对象,也可以设置为None,表示从父进程继承。

    shell设为true,程序将通过shell来执行。

    env 是字典类型,用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。

    subprocess.PIPE:在创建Popen对象时,subprocess.PIPE可以初始化stdin, stdout或stderr参数。表示与子进程通信的标准流。

    subprocess.STDOUT:创建Popen对象时,用于初始化stderr参数,表示将错误通过标准输出流输出

    ==========================================================================================================================

    Popen的方法:

    Popen.poll()

      用于检查子进程是否已经结束。设置并返回returncode属性。

    Popen.wait()

      等待子进程结束。设置并返回returncode属性。

    Popen.communicate(input=None)

      与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。

    Popen.send_signal(signal)

      向子进程发送信号。

    Popen.terminate()

      停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。

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

    ==========================================================================================================================

    简单应用:

        p=subprocess.Popen("dir", shell=True)  
        p.wait()  

      shell参数根据你要执行的命令的情况来决定,上面是dir命令,就一定要shell=True了,p.wait()可以得到命令的返回值。

    如果上面写成a=p.wait(),a就是returncode。那么输出a的话,有可能就是0【表示执行成功】。

        p=subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
        (stdoutput,erroutput) = p.communicate()  

      p.communicate会一直等到进程退出,并将标准输出和标准错误输出返回,这样就可以得到子进程的输出了。

    ==========================================================================================================================

    代码分析:

        ......
    self.root_env = {'USER': 'root', 'HOME': '/root'} def loca_cmd(self, cmd, env): p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, shell=True  #shell=true ,程序将通过shell执行) stdout,stderr = p.communicate() return stdout  #print stdout[0] => 'a' def collect_node_info(self): check_yml_cmd = "cat qmonitor_cluster.yml | grep ^[^#] " stdout = self.loca_cmd(check_yml_cmd, self.root_env) if stdout == "": self.qmonitor_node_info = {'api': '127.0.0.1', 'schedule': '127.0.0.1', 'mysql': [{'master': '127.0.0.1'}], 'qmonitor_master': '127.0.0.1', 'node_ip': [{'ip': '127.0.0.1', 'perf_num': 4}], 'jetty': '127.0.0.1'} self.qmonitor_node_list = [{'ip': '127.0.0.1', 'perf_num': 4}] else: try: import paramiko import yaml current_path = os.path.dirname(os.path.realpath(__file__)) qmonitor_cluster = os.path.join( current_path, "qmonitor_cluster.yml") with open(qmonitor_cluster) as f: text = f.read() config_dict = yaml.load(text) self.qmonitor_node_info = config_dict["qmonitor_cluster"] self.qmonitor_node_list = self.qmonitor_node_info["node_ip"] except Exception, e: self.print_sys_error( "please config yum repo and execute : yum install -y PyYAML python-paramiko") sys.exit(0)

    =====================================================================================================================================

     死锁

    如果你使用了管道,而又不去处理管道的输出,那么小心点,如果子进程输出数据过多,死锁就会发生了,比如下面的用法:

        p=subprocess.Popen("longprint", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)  
        p.wait()  

    longprint是一个假想的有大量输出的进程,那么在我的xp, Python2.5的环境下,当输出达到4096时,死锁就发生了。当然,如果我们用p.stdout.readline或者p.communicate去清理输出,那么无论输出多少,死锁都是不会发生的。或者我们不使用管道,比如不做重定向,或者重定向到文件,也都是可以避免死锁的。

  • 相关阅读:
    ajax优缺点
    关于测量专业软件使用感受及建议
    12.7
    12.6
    场景调研
    对搜狗输入法的看法及建议
    12.9
    12.8
    12.5站立会议
    12.4站立会议
  • 原文地址:https://www.cnblogs.com/blitheG/p/7495716.html
Copyright © 2011-2022 走看看