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密码:

  • 相关阅读:
    codeforces 650B
    2013 ACM区域赛长沙 H zoj 3733 (hdu 4798) Skycity
    2013 ACM区域赛长沙 I LIKE vs CANDLE(ZOJ3734) 很好的一道树形DP
    Codeforces Round #306 (Div. 2)——A——Two Substrings
    Codeforces Round #306 (Div. 2)——B暴力——Preparing Olympiad
    HDU5248——二分查找——序列变换
    HDU2255——KM算法——奔小康赚大钱
    匈牙利算法&KM算法
    HDU1059——多重部分和问题——Dividing
    HDU1058——Humble Numbers
  • 原文地址:https://www.cnblogs.com/itfat/p/7499780.html
Copyright © 2011-2022 走看看