python3 subprocess

subprocess模块允许你启动一个新的进程,连接输入/输出/错误的管道,
获得子进程的返回码。这个模块目标是代替一些老的模块,比如os.system和os.spawn.
下面我们来介绍subprocess模块的使用。

使用subprocess模块

在所有可以使用此模块的场景下首先推荐使用run()方法。更高级的用法可以直接使用Popen接口。
run()方法是在python 3.5版本中加入的。方法如下:

subprocess.run(args, *, stdin=None, input=None, stdout=None, 
stderr=None, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None)

args参数表示需要执行的命令,主进程会等待子进程执行完成,并返回一个CompletedProcess实例。

上面的一些参数只不过是一个常用的参数,下面会进行介绍。它的全部的参数是很多的,就像Popen的构造函数一样。除了timeout,input以及check参数外,其他的参数都会传递给Popen接口。也就是说Popen接口是核心。run方法只是外部的一个包装。

这个方法默认不捕获标准输出和标准错误。如果需要捕获的话,需要传递PIPE给stdout和stderr参数。

timeout参数传递给Popen.comunicate()方法。如果超时了,子进程会被杀死并且等待。TimeoutExpired会在子进程终止后被抛出。

input参数也传递给Popen.communicate()方法,从而传递给子进程的标准输入。如果要是用这个参数,必须传递一个字节序列,如果编码和错误指定了或者universal_newlines是true的话可以传递字符串。在使用的使用内部的Popen对象会自动创建,并且stdin=PIPE,stdin参数也就可能不会被用到。

check是true的情况,如果进程返回一个非零码,CalledProcessError异常会被抛出,此异常的属性包括参数,退出码和stdout,stderr。

如果编码和错误被指定,或者universal_newlines是true。stdin,stdout和stderr的文件对象就会默认使用编码和错误或者io.TextIOWrapper以文本模式打开。否则文件对象的打开方式为二进制模式。


实例:

import subprocess
def runcmd(command):
    ret = subprocess.run(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8",timeout=1)
    if ret.returncode == 0:
        print("success:",ret)
    else:
        print("error:",ret)


runcmd(["dir","/b"])#序列参数
runcmd("exit 1")#字符串参数

输出结果如下:

success: CompletedProcess(args=['dir', '/b'], returncode=0, stdout='test.py\n', stderr='')
error: CompletedProcess(args='exit 1', returncode=1, stdout='', stderr='')

run方法返回,就表示着命令执行完成。看到返回一个CompletedProcess实例,参数包括:args,returncode,stdout,stderr.


需要解释一下:
shell=True:表示执行的是shell命令。
subprocess.PIPE:可以用给stdout,stdin,stderr.表示为标准流打开一个管道,常用来捕获子进程的输出和错误.
encoding:指出了标准流的编码格式,不指定的话默认是二进制的.
timeout:指出子进程的超时时间。如果超时会抛出一个TimeoutExpired异常。


Popen构造函数

Popen是subprocess的核心,子进程的创建和管理都靠它处理。它提供了很多灵活的参数,可以让开发者实现一些不太常见的实例。构造函数如下:

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, 
preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, 
startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(),
*, encoding=None, errors=None)

此类可以在一个新的进程中执行子程序。在POSIX系统中,这个类使用os.execvp()来执行子程序。在windows中使用Windows的CreateProcess()方法。参数解释如下:


args:表示要执行的命令,应当是一个参数的序列,或者就是一个字符串。一般推荐使用序列进行传递。但是如果shell指定为True的话,推荐使用字符串。

bufsize:缓冲区大小。当创建标准流的管道对象时使用。默认-1
0:不使用缓冲区
1:表示行缓冲,仅当universal_newlines=True时可用,也就是文本模式
正数:表示缓冲区大小
负数:表示使用系统默认的缓冲区大小。

executable:指定一个替代的程序去执行。这个参数几乎不会被用到。当shell=False的时候此参数替代args执行,然而,原始的args依旧传递给程序。很多程序把args当做命令的名字,而不是真正执行的程序。如果shell=True,在POSIX上此参数指定一个替代的shell来替换默认的/bin/sh。

stdin,stdout和stderr:分别表示标准输入,输出,和错误流。可用的参数是PIPE,DEVNULL,文件描述符,文件对象或者None。

preexec_fn:设置一个可访问的对象,在子进程执行之前会调用这个对象。

close_fds:如果是Ture,那么文件描述符除了0,1和2外,在子进程执行之前都会被关闭。在POSIX上总是为True.在windows上,标准流为None是为Ture,不能通知指定True和标准流。

cwd:在子进程执行之前改变工作目录,
restore_signals:存储进程信号,默认为True
start_new_session:如果是True,则在子进程执行之前条用系统setsid方法。
encoding,errors:如果指定了,那么标准流会以文本模式打开。


Popen对象方法

poll():检查进程是否终止,如果终止返回returncode,否则返回None。
wait(timeout):等待子进程终止。
communicate(input,timeout):和子进程交互,发送和读取数据。
send_signal(singnal):发送信号到子进程
terminate():停止子进程,也就是发送SIGTERM信号到子进程。
kill():杀死子进程。发送SIGKILL信号到子进程

下面是一个简单的实例:

import time
import subprocess

def cmd(command):
    subp = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8")
    subp.wait(2)
    if subp.poll() == 0:
        print(subp.communicate()[1])
    else:
        print("失败")



cmd("java -version")
cmd("exit 1")

输出结果如下:

java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)

失败
[Finished in 0.3s]

———————————未完待续———————————–

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值