python的subprocess.Popen()的简单用法

英语原文: https://www.python.org/dev/peps/pep-0324/

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):

 

构造函数参数分析:

-args  应该是字符串或程序参数序列,要执行的程序名应在参数序列的第一个位置上,后面可以跟

   程序所需要的命令行参数,也可以被显式设置通过用executable参数。

          在UNIX 上当 shell=False(默认), 在这种情况下类Popen 用  os.execvp() 来执行子程序,

   args  应该是一个序列,字符串也被看作只有程序名的序列。

   在UNIX 上,当 shell=True, 如果 args 是字符串,它将作为命令行字符串通过shell 执行.如果是一个序列,

   它的第一个元素将作为命令行字符串,后面的元素被作为附加的shell参数。

   在 Windows 上,类Popen 用 CreateProcess() 来执行子程序,它以字符串作为参数。 

   如果args 是一个序列,它将通过 list2cmdline 方法转化为字符串,要注意的是不是所有的MS Windows

   用相同的方法解释命令行。

- bufsize 如果被赋值,值将作为内建函数open() 的参数,0意味着无缓冲,1就是行缓冲,任何其它的正值,

   意味着用和给定值大小接近的一个缓冲,负值就使用系统默认的缓冲尺寸,类的默认值是0无缓冲

          (实时清空缓冲区)

- stdin, stdout and stderr 分别代表子程序的标准输入,标准输出,标准错误输出的文件句柄,

            有效值可以是一个存在的文件对象,   或者一个文件描述符,或者 PIPE(一个正整数)或者是None。

            若赋值为PIPE ,就会为子程序创建新管道pipe , 若为None ,就不会出现从定向,

            子程序继承父程序的文件句柄。另外,stderr 可以是STDOUT, 这表明子程序的错误数据可以被获得

            并发送到stdout输出.

-  preexec_fn 被赋值一个可以调用的对象,这个对象在子程序执行前调用到子进程,

- close_fds 是true , 所有的文件描述符号除了0,1,2 在子程序执行前将被关闭。

- shell 是true ,命令行参数将通过shell 执行。

- cwd 不是None ,在子程序执行前,当前的工作目录将变为cwd。

- env 不是None , 它将为新进程指定环境变量。

- universal_newlines是true, 文件对象stdout,stderr将被打开作为text文件,行将被中断通过

   这些 '\n' (Unix), '\r' (Mac), '\r\n ' (Win)换行符号,所有这些外部的符号被python 看作'\n' .

   注意这些特征只在python支持通用换行的时候有效(默认支持)

   communicate()方法没有更新对文件换行属性的支持

- startupinfo , creationflags 被赋值,它将传递一个潜在的创建进程的方法CreateProcess(),

   它能指定主窗口外观,和新进程的优先等级(Win上有效)

          subprocess.startupinfo 详解网址:

          http://www.programcreek.com/python/example/5376/subprocess.STARTUPINFO

 

 

类Popen的成员函数

poll() 检测子进程是否终止,返回执行结果状态

wait() 等待子进程终止,返回执行结果

communicate(input=None) :与子进程交流,把该方法括号中的数据发送到子进程的标准输入stdin,

   数据格式应该是字符串,若为None,则不给子进程发送数据。返回的元组从stdout,stderr中读取

   数据直到文件结尾。

   communicate() returns a tuple (stdout, stderr).

   返回包含两个元素的元组,第一是stdout输出的字符串,第二个是stderr的字符串,

out, err = std.communicate(), err = std.communicate()

   

          注意:输出的字符串缓存在内存中,因此,如果输出数据较多时候应该避免使用这个方法。

类Popen的成员变量:

stdin 如果stdin=PIPE,这个属性是个文件对象,提供子进程的输入,否则它是None

   obj.stdin.write(" args ")

stdout 如果stdout=PIPE,这个属性是个文件对象,提供子进程的输出,否则它是None

   obj.stdout.read() 

stderr 如果stderr=PIPE,这个属性是个文件对象,提供子进程的错误输出,否则它是None

pid  子程序的进程ID

returncode 子程序返回码,None 说明子进程没有终止,负值-N 说明被符号-N终止 (UNIX only)。

 

Popen模块也定义了2个便捷函数  

 

- call(*args, **kwargs):

 

       运行带参数的命令,等待命令执行完成,返回返回码的属性。

 

   这里的参数与作为类Popen的构造参数一样,

   只有命令时候用 call("cmd"),命令带参数时候要用list形式['cmd', 'args']

   例如:

   retcode = call('ls')

   retcode = call(["ls", "-l"])

   retcode = call( ("ls", "-l") )

---------------------------------------------------------------------

 

用法:

  • 1. Window中图形界面python程序调用exe阻止dos窗口的弹出,可如下定义 startupinfo  参数
from subprocess import *  
from subprocess import  STARTUPINFO #对于python2.7需要单独引用STARTUPINFO

import os
startupinfo = STARTUPINFO()
startupinfo.dwFlags |=  STARTF_USESHOWWINDOW
startupinfo.wShowWindow =  SW_HIDE

Popen("cmd",stdin = PIPE, stdout = PIPE,stderr=PIPE,startupinfo=startupinfo)

把 startupinfo 定义到一个函数中:

def supress_window():
    if os.name == 'nt':
        startupinfo =  STARTUPINFO() #only used in python3
        startupinfo.dwFlags |=  STARTF_USESHOWWINDOW
        startupinfo.wShowWindow =  SW_HIDE
        return startupinfo
    return None

 

--------------------------------------------

 

  • 2. python(2.7可用,3.x不行)调用 '/home/app' 文件:
#! /usr/bin/python2.7
from subprocess import *
import os 
p = Popen('/home/app', stdin =  PIPE,stdout = PIPE, stderr = PIPE )  
p.stdin.write('3 \n')   
p.stdin.write('4 \n')   
print p.stdout.read()   

被调用程序app的c++ 的源码:

#include    
using namespace std;   
int main(int argc, const char *artv[])   
{   
  int x, y;   
  cin >> x;   
  cin >> y;   
  cout << x << " + " << y << " = " << x + y << endl;   
  return 0;   
} 

 

 

  • 3. 对于python调用gnuplot画图

Popen.write()方法,在python2中参数可以是字符串,在python3中要加上b把字符串转化为二进制

#! /usr/bin/python3.5   
from subprocess import *
gnuplot= Popen('/usr/bin/gnuplot',stdin = PIPE,stdout=PIPE,stderr=PIPE).stdin
gnuplot.write(b"set terminal jpeg\n")
gnuplot.write(b"set output 'plot.jpg'\n")
gnuplot.write(b"set xlabel 'site'\n")
gnuplot.write(b"set ylabel 'value'\n")
gnuplot.write(b"set title '3Z code'\n")
gnuplot.write(b"plot sin(x)\n")
gnuplot.flush()

win下要有关闭进程的语句

from subprocess import *  
gnuplot= Popen('gnuplot',stdin = PIPE, stderr=PIPE).stdin  
gnuplot.write(b"set terminal jpeg \n")  
gnuplot.write(b"set output 'plot.jpg' \n")  
gnuplot.write(b"set xlabel 'site' \n")  
gnuplot.write(b"set ylabel 'value' \n")  
gnuplot.write(b"set title '3Z code' \n")  
gnuplot.write(b"plot sin(x) \n")  
gnuplot.flush()
gnuplot.close()

 

 

 

 

 

 

 

 

            

你可能感兴趣的:(Python)