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

    The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions:

    os.system :输出命令到结果到屏幕,返回命令执行状态

    os.spawn*

    The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly.

    The run() function was added in Python 3.5; if you need to retain compatibility with older versions, see the Older high-level API section.

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

    Run the command described by args. Wait for command to complete, then return a CompletedProcess instance.

    The arguments shown above are merely the most common ones, described below in Frequently Used Arguments (hence the use of keyword-only notation in the abbreviated signature). The full function signature is largely the same as that of the Popen constructor - apart from timeout, input and check, all the arguments to this function are passed through to that interface.

    This does not capture stdout or stderr by default. To do so, pass PIPE for the stdout and/or stderr arguments.

    The timeout argument is passed to Popen.communicate(). If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated.

    The input argument is passed to Popen.communicate() and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if universal_newlines=True. When used, the internal Popen object is automatically created withstdin=PIPE, and the stdin argument may not be used as well.

    If check is True, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.

    在os模块中,输出系统命令有这么两个命令。

    os.system :输出命令到结果到屏幕,返回命令执行状态

    os.popen().read():会保存命令的执行结果输出,不会返回命令执行状态

    subprocess模块

    subprocess.run():这个是3.5之后的方法

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

    运行由args描述的命令。等待命令完成,然后返回一个CompletedProcess实例。

    #linux下执行
    >>> import subprocess
    >>> subprocess.run(["df"])    #不加参数也可以这么写subprocess.run("df")
    Filesystem     1K-blocks    Used Available Use% Mounted on
    /dev/sda3       18796848 1830852  16004512  11% /
    tmpfs             502068       0    502068   0% /dev/shm
    /dev/sda1         194241   33790    150211  19% /boot
    CompletedProcess(args=['df'], returncode=0)
    
    #如果需过滤参数,要这么写
    >>> subprocess.run("df -h |grep sda1",shell = True)
    /dev/sda1       190M   33M  147M  19% /boot
    CompletedProcess(args='df -h |grep sda1', returncode=0)
    
    #保存输出结果
    >>> a = subprocess.run("df -h |grep sda1",shell = True,stdout = subprocess.PIPE)
    >>> print(a)
    CompletedProcess(args='df -h |grep sda1', returncode=0, stdout=b'/dev/sda1       190M   33M  147M  19% /boot
    ')
    
    #读取我们想要的内容
    >>> a.args
    'df -h |grep sda1'
    >>> a.returncode
    0
    >>> a.stdout
    b'/dev/sda1       190M   33M  147M  19% /boot
    '
    
    #输出是字节形式的,转换成字符串
    >>> a.stdout.decode("utf-8")
    '/dev/sda1       190M   33M  147M  19% /boot
    '
    
    #还有个参数是stderr,错误输出
    >>> a = subprocess.run("dfasdad",shell = True,stdout = subprocess.PIPE,stderr = subprocess.PIPE)
    >>> a.stdout
    b''
    >>> a.stderr
    b'/bin/sh: dfasdad: command not found
    '
    #当命令输错的时候,就在stderr输出了。
    
    #windows下执行
    >>> import subprocess
    >>> subprocess.run("dir",shell = True)
    驱动器 C 中的卷是 OS
     卷的序列号是 8012-5F9E
    
     C:UsersMrs shao 的目录
    
    2017/06/05  23:14    <DIR>          .
    2017/06/05  23:14    <DIR>          ..
    2016/10/28  08:57    <DIR>          .android
    2017/06/15  20:51             2,567 .bash_history
    2017/04/24  17:18    <DIR>          .designer
    2017/06/05  22:09                51 .gitconfig
    2017/04/05  20:55    <DIR>          .idlerc
    2017/04/30  18:28    <DIR>          .oracle_jre_usage
    2017/04/29  19:48    <DIR>          .PyCharm2017.1
    2017/06/05  23:14             1,189 .viminfo
    2016/11/18  20:52    <DIR>          .VirtualBox
    2016/10/27  19:05    <DIR>          AppData
    2017/02/21  13:25    <DIR>          Contacts
    2017/06/19  22:45    <DIR>          Desktop
    2017/06/16  17:35    <DIR>          Documents
    2017/06/20  12:14    <DIR>          Downloads
    2017/05/19  10:15    <DIR>          fancy
    2017/02/21  13:25    <DIR>          Favorites
    2017/02/21  13:25    <DIR>          Links
    2017/03/05  15:13    <DIR>          LocalStorage
    2017/02/21  13:25    <DIR>          Music
    2017/04/22  20:57    <DIR>          OneDrive
    2017/03/13  15:23    <DIR>          Pictures
    2017/05/13  12:03    <DIR>          Program Files
    2017/04/29  19:47    <DIR>          PyCharm 2017.1.2
    2017/04/24  13:14    <DIR>          PycharmProjects
    2016/10/20  12:08    <DIR>          Roaming
    2017/02/21  13:25    <DIR>          Saved Games
    2017/02/21  13:25    <DIR>          Searches
    2017/06/25  16:23    <DIR>          Videos
    2017/03/05  15:13            18,432 WebpageIcons.db
                   4 个文件         22,239 字节
                  27 个目录 38,806,908,928 可用字节
    CompletedProcess(args='dir', returncode=0)
    
    #在windows下用法大致与linux下相同,不过要注意编码。
    >>> import subprocess
    >>> a = subprocess.run("dir",shell = True,stdout = subprocess.PIPE)
    >>> print(a.stdout.decode("gb2312"))   #windows下是要用这个解码,因为当你读取windows下的数据实际上是gb2312的数据格式,所以你要先解码成unicode的格式。
    这里结果就不附上了,和上面一致
    

      

    常用subprocess方法示例

    基于linux下的

    #执行命令,并返回命令执行状态 , 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')

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

    #执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给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

    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% / '

    用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

    linux下实现自动输入密码

    subprocess.Popen("echo '123456' | sudo -S chmod 777 aaa",shell = True)
    

      

     

    >>> res = subprocess.Popen("dir",shell=True,stdout=subprocess.PIPE).stdout.read()  #保存输出数据
    
    >>> print(res.decode("gb2312"))
     驱动器 C 中的卷是 OS
     卷的序列号是 8012-5F9E
    
     C:UsersMrs shao 的目录
    
    2017/06/28  16:36    <DIR>          .
    2017/06/28  16:36    <DIR>          ..
    2016/10/28  08:57    <DIR>          .android
    2017/06/15  20:51             2,567 .bash_history
    2017/04/24  17:18    <DIR>          .designer
    2017/06/05  22:09                51 .gitconfig
    2017/04/05  20:55    <DIR>          .idlerc
    2017/04/30  18:28    <DIR>          .oracle_jre_usage
    2017/04/29  19:48    <DIR>          .PyCharm2017.1
    2017/06/05  23:14             1,189 .viminfo
    2016/11/18  20:52    <DIR>          .VirtualBox
    2016/10/27  19:05    <DIR>          AppData
    2017/02/21  13:25    <DIR>          Contacts
    2017/06/19  22:45    <DIR>          Desktop
    2017/06/16  17:35    <DIR>          Documents
    2017/06/28  09:48    <DIR>          Downloads
    2017/05/19  10:15    <DIR>          fancy
    2017/02/21  13:25    <DIR>          Favorites
    2017/02/21  13:25    <DIR>          Links
    2017/03/05  15:13    <DIR>          LocalStorage
    2017/02/21  13:25    <DIR>          Music
    2017/04/22  20:57    <DIR>          OneDrive
    2017/03/13  15:23    <DIR>          Pictures
    2017/05/13  12:03    <DIR>          Program Files
    2017/04/29  19:47    <DIR>          PyCharm 2017.1.2
    2017/04/24  13:14    <DIR>          PycharmProjects
    2016/10/20  12:08    <DIR>          Roaming
    2017/02/21  13:25    <DIR>          Saved Games
    2017/02/21  13:25    <DIR>          Searches
    2017/06/28  11:41    <DIR>          Videos
    2017/03/05  15:13            18,432 WebpageIcons.db
                   4 个文件         22,239 字节
                  27 个目录 38,216,822,784 可用字节
    

      

     

     
  • 相关阅读:
    判断一个表里面有没有相同的数据
    ASP.NET面试题公司必考<1>
    jQuery 实现三级联动
    javascript 面试大全
    Javascript 实现倒计时跳转页面代码
    SQL删除重复数据只保留一条 .
    编写SQL语句查询出每个各科班分数最高的同学的名字,班级名称,课程名称,分数
    Silverlight 和javascript 之间的调用
    delphi 开放数组参数
    SPCOMM控件在Delphi7.0串口通信中的应用
  • 原文地址:https://www.cnblogs.com/zj-luxj/p/7067463.html
Copyright © 2011-2022 走看看