• Python的subprocess模块


    试想一下这样的场景,你的笔记本电脑在图书馆正常的放着,然后你去了教学区上课去了。然后你想看一下自己电脑前有没有人,然后就可以通过手机发送一条命令,让笔记本电脑拍照,并发送给手机。或者你的同学在你的电脑边,然后你远程用手机发一条指令,让电脑发出鬼叫或者播放音乐什么的··· ···

    但是遗憾的是这个”远程操作“功能成为了瓶颈,其实就是怎么让当前进程去执行额外命令。 还好遇到了subprocess。然后就可以很方便的”为所欲为“啦。

    os模块

    也许在subprocess之前,你可能听说过os模块。如:

    import os
    cmdstr = "some cmd command"
    os.system(cmdstr)
    

    这种方式可以很轻松的执行Windows上的命令,但是缺点是: 
    不受控,没有返回结果。对于简单的需求而言还行,但是对于需要获取返回结果的就不太适用了。

    入门

    相比较subprocess, 执行一条命令就方便多了。比如实现与os模块相同功能的话,可以使用如下代码:

    import subprocess
    
    cmdstr = "some cmd command"
    subprocess.call(cmdstr)
    

    当你想执行带有命令行参数的命令的时候,也是比较方便的。可以使用一个列表盛放需要执行的命令。subprocess底层会默认将这个列表拼装成命令字符串。

    import subprocess
    cmdstr1 = 'ping'
    cmdstr2 = 'www.douban.com'
    subprocess.call([cmdstr1, cmdstr2])
    

    除此之外,还有 
    subprocess.check_call()

    • subprocess.check_out_put

    等函数。按需选取就行了。 

    subprocess模块是python从2.4版本开始引入的模块。主要用来取代 一些旧的模块方法,如os.system、os.spawn*、os.popen*、commands.*等。subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

    常用方法:

    subprocess.call():执行命令,并返回执行状态,其中shell参数为False时,命令需要通过列表的方式传入,当shell为True时,可直接传入命令

    subprocess.check_call():用法与subprocess.call()类似,区别是,当返回值不为0时,直接抛出异常

    subprocess.check_output():用法与上面两个方法类似,区别是,如果当返回值为0时,直接返回输出结果,如果返回值不为0,直接抛出异常。需要说明的是,该方法在python3.x中才有。

    subprocess.Popen():

    在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等。这个时候我们就需要使用到suprocess的Popen()方法。该方法有以下参数:

    args:shell命令,可以是字符串,或者序列类型,如list,tuple。

    bufsize:缓冲区大小,可不用关心

    stdin,stdout,stderr:分别表示程序的标准输入,标准输出及标准错误

    shell:与上面方法中用法相同

    cwd:用于设置子进程的当前目录

    env:用于指定子进程的环境变量。如果env=None,则默认从父进程继承环境变量

    universal_newlines:不同系统的的换行符不同,当该参数设定为true时,则表示使用 作为换行符

    管道

    熟悉命令行的同行肯定对于管道|不陌生了。工作在进程之间,为操作的提供了巨大的便利。尤其是linux爱好者,管道的魅力更甚。

    当然了,windows上也是支持的,比方说,找出笔记本电脑上网卡网段为192.开头的信息。就可以这样办。 

    同样,在subprocess中,PIPE的原理也是一样的。如果需要让管道起作用的话,Popen内相关参数要设置为PIPE即可。这一点可以参照文档,这里不再叙述。

    进程交互

    典型的场景就是,父进程内开启一个子进程,并获取子进程的执行的返回结果。

    这个时候,就需要指定stdin, stdout为PIPE形式了。否则的话,两个进程之间是无法进行交流的。这就好比两个池塘,相互有自己的资源,如果内有一个通道的话,两个池塘就没办法”交流“。

    1.py

    import sys
    s = "this is from {}".format(__file__)
    
    sys.stdout.write(s)
    

    2.py

    import subprocess
    import sys
    try:
        child = subprocess.Popen('python ./1.py', stdout=subprocess.PIPE,stdin=subprocess.PIPE,stderr=subprocess.PIPE)
        print child.stdout.readline()
    
    except Exception as e:
        print e
    

    运行结果

    如上,不难看出。父进程2.py最终得到了子进程1.py的运行结果的。

    虽然这个很明显是单向的”交流“,但是已经满足博主的需求了。这就好比士兵对于命令的服从,给出指令,尽管执行便是,最后把结果反馈回来即可。

    但是如果非要双向交流的话,那就得借助于communicate()方法了。

    总结

    本文简单的介绍了相关于subprocess模块的使用,比较通俗,也比较浅显。对于简单需求应该是够用的啦,但是非要深挖的话,还是得去看官方文档的好。

  • 相关阅读:
    JS中的原型规则与原型链
    JS中的“==”与强制类型转换
    协作开发中常用的Git命令小结
    JavaScript变量类型检测总结
    IDEA IntelliJ常用设置以及快捷键(转)
    Spring 发送 Email
    SSM框架的整合思路&功能实现
    使用Eclipse把java文件打包成jar 含有第三方jar库的jar包
    基于CDH5.x 下面使用eclipse 操作hive 。使用java通过jdbc连接HIVESERVICE 创建表
    Volley源码学习笔记
  • 原文地址:https://www.cnblogs.com/strive-man/p/8618029.html
Copyright © 2020-2023  润新知