zoukankan      html  css  js  c++  java
  • subprocess模块

    subprocess模块是

    os.system作用os.system(cmd)的返回值只会有0(成功)

    命令执行的返回值,0就是表示命令成功,非0表示命令失败(不一定是1)

    但是我们想把命令的输出保存下来怎么操作呢?用函数os.popen("dir")

    我们发现格式是乱的,我们现在print下这个结果:print就会把 弄成换行,变成好看了。

    os.popen("dir").read() #会保存命令的执行结果输出

    但是这个时候,没有返回的状态,不知道是否输出成功没。

    在py2.7里,有commands模块,

    commands.getstatusoutput("dir")可以得到返回结果是一个元祖

    第一个值就是执行命令的结果,

    第二个是一个字符串,不过是字节类型二进制。

    但是在win下执行commands这个模块是会报错的。返回执行结果是1,见上图。

    在linux下是可以正常执行的。

    res[0]返回的是成功的状态0,res[1]是命令返回的结果。

    在python3里已经没有commands模块了:

    os.spawn* 产生一个新进程
    这两个模块的替换。上面这两个模块会慢慢被替换掉,逐步不使用了。

    常用subprocess方法示例

    subprocess.run(方法)

    subprocess.run(["df","-h"]),写法奇特,注意有两个中刮号

    如果你想执行命令,有管道的情况,就是有"| grep"的情况,就不能用这种一个一个参数传进去了:

    要直接写在一个字符串里,而且后面要加一个参数shell=True

    建议推荐使用.run()的方法~!

    如果不涉及管道,那么就把命令当作一个列表,然后传进去。

    如果涉及管道命令,那么就直接用一个字符串,然后参数shell=True来执行命令。

    #执行命令,返回命令执行状态 , 0 or 非0

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

    #执行命令,如果命令结果为0,就正常返回,否则抛异常

    >>> subprocess.check_call(["ls", "-l"])
    0

     

    #接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果 
    >>> subprocess.getstatusoutput('ls /bin/ls')
    (0, '/bin/ls')

    这个方法跟 commands.getstatusoutput一样作用

    一般我们都用这个方法足够了!!!

    #接收字符串格式命令,并返回结果
    >>> subprocess.getoutput('ls /bin/ls')
    '/bin/ls'

    这个方法类似os.popen一样

    #执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res
    >>> res=subprocess.check_output(['ls','-l']) 
    >>> res
    b'total 0 drwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM '

    #上面那些方法,底层都是封装的subprocess.Popen
    poll()
    Check if child process has terminated. Returns returncode

    如果进程结束了,就返回执行代码。意思就是说这个命令的执行时间很长,你不知道啥时候结束,那么可以用这个方法,去查命令是否执行结束!

    这个时候,我们可以不停的调用res.poll来查询这个命令是否结束:

    而下面的wait()方法跟poll就不一样,它是一直等待到命令执行结束,然后返回命令执行的结果。

    wait()

    Wait for child process to terminate. Returns returncode attribute.

    terminate() 杀掉所启动进程

    communicate() 等待任务结束

    stdin 标准输入


    stdout 标准输出

    stderr 标准错误

    pid
    The process ID of the child process.

    #例子
    >>> p = subprocess.Popen("df -h|grep disk",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True)
    >>> p.stdout.read()
    b'/dev/disk1 465Gi 64Gi 400Gi 14% 16901472 104938142 14% / '

    参数,stdout=subprocess.PIPE表示把数据先放到管道PIPE里,然后输出到屏幕,stderr=subprocess.PIPE把执行命令返回的错误放到管道里,然后输出到屏幕,stdin=subprocess.PIPE输入

    subprocess.Popen()最大的好处,就是可以得到错误命令的输出结果!run只能得到正确的结果

    调用subprocess.run(...)是推荐的常用方法,在大多数情况下能满足需求,但如果你可能需要进行一些复杂的与系统的交互的话,你还可以用subprocess.Popen(),语法如下:

    可用参数:

        • args:shell命令,可以是字符串或者序列类型(如:list,元组)
        • bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
        • stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
        • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
        • close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
          所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
        • shell:同上
        • cwd:用于设置子进程的当前目录,设置环境在哪个路径下执行脚本
        • env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
        • universal_newlines:不同系统的换行符不同,True -> 同意使用
        • startupinfo与createionflags只在windows下有效
          将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

    终端输入的命令分为两种:

    • 输入即可得到输出,如:ifconfig
    • 输入进行某环境,依赖再输入,如:python

    需要交互的命令示例

    import subprocess
     
    obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    obj.stdin.write('print 1 
     ')
    obj.stdin.write('print 2 
     ')
    obj.stdin.write('print 3 
     ')
    obj.stdin.write('print 4 
     ')
     
    out_error_list = obj.communicate(timeout=10)
    print out_error_list

    subprocess实现sudo 自动输入密码

     因为权限不够,想自动输入sudo的密码,现象如下图:

    正常情况下,用一条命令来实现自动输入sudo密码:

  • 相关阅读:
    关于在MAC上进行 LARAVEL 环境 Homestead 安装过程记录
    js 贷款计算器
    js 实现阶乘
    js 两点间距离函数
    composer Your requirements could not be resolved to an installable set of packages
    vue 项目优化记录 持续更新...
    vue 项目打包
    vue 真机调试页面出现空白
    vue 真机调试
    谈谈-Android状态栏的编辑
  • 原文地址:https://www.cnblogs.com/itfat/p/7499780.html
Copyright © 2011-2022 走看看