python - 标准库: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:可以是字符串或者序列类型(如: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去清理输出,那么无论输出多少,死锁都是不会发生的。或者我们不使用管道,比如不做重定向,或者重定向到文件,也都是可以避免死锁的。
python - 标准库:subprocess模块的更多相关文章
- [python标准库]Pickle模块
Pickle-------python对象序列化 本文主要阐述以下几点: 1.pickle模块简介 2.pickle模块提供的方法 3.注意事项 4.实例解析 1.pickle模块简介 The pic ...
- Python 标准库 ConfigParser 模块 的使用
Python 标准库 ConfigParser 模块 的使用 demo #!/usr/bin/env python # coding=utf-8 import ConfigParser import ...
- Python标准库——collections模块的Counter类
1.collections模块 collections模块自Python 2.4版本开始被引入,包含了dict.set.list.tuple以外的一些特殊的容器类型,分别是: OrderedDict类 ...
- [python标准库]XML模块
1.什么是XML XML是可扩展标记语言(Extensible Markup Language)的缩写,其中的 标记(markup)是关键部分.您可以创建内容,然后使用限定标记标记它,从而使每个单词. ...
- 【python】Python标准库defaultdict模块
来源:http://www.ynpxrz.com/n1031711c2023.aspx Python标准库中collections对集合类型的数据结构进行了很多拓展操作,这些操作在我们使用集合的时候会 ...
- python 标准库 -- subprocess
subprocess 主要功能室执行外部的命令和程序 一个进程可 fork 一个子进程, 并让这个子进程 exec 另外一个程序. 在 python 中, 可以通过标准库中的 subprocess 包 ...
- Python标准库--os模块
这个模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话,这个模块是尤为重要的.即它允许一个程序在编写后不需要任何改动,也不会发生任何问题,就可以在Linux和Windows下运行.一个例 ...
- python标准库 bisect模块
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #bisect #作用:维护有序列表,而不必在每次向列表增加一个元素 ...
- python标准库 sysconfig模块
# -*- coding: utf-8 -*-# python:2.x__author__ = 'Administrator'import sysconfig#sysconfig:解释器编译时配置#作 ...
- Python标准库 -- UUID模块(生成唯一标识)
UUID是什么: UUID: 通用唯一标识符 ( Universally Unique Identifier ),对于所有的UUID它可以保证在空间和时间上的唯一性,也称为GUID,全称为: UUID ...
随机推荐
- HBASE学习笔记(三)
一. 1.预切割:在创建表的时候,预先对表进行region切割.切割线就是rowkey $hbase> create '] $hbase>create 'ns2:t3',SPLITS=&g ...
- generator 到 async 的简单理解。
generator 到 async 的简单理解.觉得实现方式很有意思. 1. generator generator 函数返回一个遍历器对象 遍历器对象 每次调用next 方法 返回 有着value ...
- 十一、LaTex中的矩阵
- Windows Server IIS设置计划任务重启
Windows Server ,IIS设置计划任务重启. echo ----->>c:\log_iisreset.txt && echo %date% %time% &g ...
- windows2008R2下安装sqlserver2008R2时,点setup.exe应用程序无法打开错误代码0xc0150004
windows2008R2下安装sqlserver2008R2时,点setup.exe应用程序无法打开错误代码0xc0150004 问题截图: 网上查的答案都是需要安装.net framework 3 ...
- juniper 命令
show chassis hardware 查看系统硬件配置,fpc表示板卡,pic表示板卡中的槽位,xcvr表示板卡中的槽位的端口位置 show chassis envirmonent 查看系统运行 ...
- Codeforces Gym 100814C Connecting Graph 树剖并查集/LCA并查集
初始的时候有一个只有n个点的图(n <= 1e5), 现在进行m( m <= 1e5 )次操作 每次操作要么添加一条无向边, 要么询问之前结点u和v最早在哪一次操作的时候连通了 /* * ...
- Java基本的程序结构设计 数组
声明数组: int[] a; int a[]; 两种方式.一般选择第一种,比较一目了然. 初始化,必须指定长度: int[] a = new int[10]; int[] a = {1,2,3}; 初 ...
- Docker报错解决
今天我在学习docker的时候,用docker安装nginx的时候报了如下错误: 尝试了卸载docker重装,删除nginx,删除nginx镜像文件都没有用,最后发现还是Linux和docker版本兼 ...
- eclipse修改代码后都需要clean的解决办法
问题描述: 用STS(类似于Eclipse)正在开发一个JavaWeb项目,但不知怎么的有一天,修改完Java代码,点击运行Tomcat,发现根本没有修改.刚刚开始的时候,因为一开始没找到原因而且工期 ...