• Python中的subprocess模块


    Subprocess干嘛用的?

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

    也就是说subprocess就是OS模块的升级版。

     subprocess模块中的常用函数

    函数描述
    subprocess.run() Python 3.5中新增的函数。执行指定的命令,等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。
    subprocess.call() 执行指定的命令,返回命令执行状态,其功能类似于os.system(cmd)。
    subprocess.check_call() Python 2.5中新增的函数。 执行指定的命令,如果执行成功则返回状态码,否则抛出异常。其功能等价于subprocess.run(..., check=True)。
    subprocess.check_output() Python 2.7中新增的的函数。执行指定的命令,如果执行状态码为0则返回命令执行结果,否则抛出异常。
    subprocess.getoutput(cmd) 接收字符串格式的命令,执行命令并返回执行结果,其功能类似于os.popen(cmd).read()和commands.getoutput(cmd)。
    subprocess.getstatusoutput(cmd) 执行cmd命令,返回一个元组(命令执行状态, 命令执行结果输出),其功能类似于commands.getstatusoutput()。

    1.subprocess.call


    父进程等待子进程执行命令,返回子进程执行命令的状态码,如果出现错误,不进行报错

    第二个参数默认为False,Flase参数为的时候命令需要通过列表的方式传入,为True的时候可以直接传入命令。

    【在Python的console界面中我们是能够看到命令结果的,只是获取不到。想获取执行的返回结果,请看check_output。】

    【不进行报错解释:如果我们执行的命令在执行时,操作系统不识别,系统会返回一个错误,如:abc命令不存在,这个结果会在console界面中显示出来,但是我们的Python解释器不会提示任何信息,如果想让Python解释器也进行报错,请看check_call】

    >>> import subprocess
    >>> obj = subprocess.call(['df','-h'],shell=False)
    文件系统        容量  已用  可用 已用% 挂载点
    udev            5.8G     0  5.8G    0% /dev
    tmpfs           1.2G  1.8M  1.2G    1% /run
    /dev/sda6       393G  137G  237G   37% /
    tmpfs           5.8G   51M  5.8G    1% /dev/shm
    tmpfs           5.0M  4.0K  5.0M    1% /run/lock
    tmpfs           5.8G     0  5.8G    0% /sys/fs/cgroup
    tmpfs           1.2G   48K  1.2G    1% /run/user/1000
    /dev/sda5       412G   26G  386G    7% /media/i3ekr/软件
    /dev/sda1       121G   24G   97G   20% /media/i3ekr/F6AE5B1CAE5AD529
    >>> obj = subprocess.call(('df -h'),shell=True)
    文件系统        容量  已用  可用 已用% 挂载点
    udev            5.8G     0  5.8G    0% /dev
    tmpfs           1.2G  1.8M  1.2G    1% /run
    /dev/sda6       393G  137G  237G   37% /
    tmpfs           5.8G   49M  5.8G    1% /dev/shm
    tmpfs           5.0M  4.0K  5.0M    1% /run/lock
    tmpfs           5.8G     0  5.8G    0% /sys/fs/cgroup
    tmpfs           1.2G   48K  1.2G    1% /run/user/1000
    /dev/sda5       412G   26G  386G    7% /media/i3ekr/软件
    /dev/sda1       121G   24G   97G   20% /media/i3ekr/F6AE5B1CAE5AD529
    注:shell=True参数会让subprocess.Popen接受字符串类型的变量作为命令,并调用shell去执行这个字符串.见而言之就是将输入的参数调用shell去执行,如果不调用那可能就会出现命令找不到的情况.
    当shell=False是,subprocess.Popen只接受数组变量作为命令,并将数组的第一个元素作为命令,剩下的全部作为该命令的参数。 默认情况下为false.

     2.subprocess.check_call()


    用法和call作用一样,和call的区别是返回值不为0(也就是命令不正确)的时候直接抛出异常。

    >>> obj = subprocess.check_call('qwe',shell=False)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python2.7/subprocess.py", line 181, in check_call
        retcode = call(*popenargs, **kwargs)
      File "/usr/lib/python2.7/subprocess.py", line 168, in call
        return Popen(*popenargs, **kwargs).wait()
      File "/usr/lib/python2.7/subprocess.py", line 390, in __init__
        errread, errwrite)
      File "/usr/lib/python2.7/subprocess.py", line 1025, in _execute_child
        raise child_exception
    OSError: [Errno 2] No such file or directory
    >>> obj = subprocess.check_call('df',shell=False)
    文件系统           1K-块      已用      可用 已用% 挂载点
    udev             6013400         0   6013400    0% /dev
    tmpfs            1208056      1836   1206220    1% /run
    /dev/sda6      411798952 143162248 247648800   37% /
    tmpfs            6040264     48768   5991496    1% /dev/shm
    tmpfs               5120         4      5116    1% /run/lock
    tmpfs            6040264         0   6040264    0% /sys/fs/cgroup
    tmpfs            1208052        48   1208004    1% /run/user/1000
    /dev/sda5      431498236  27213864 404284372    7% /media/i3ekr/软件
    /dev/sda1      125830140  24482072 101348068   20% /media/i3ekr/F6AE5B1CAE5AD529

    可以用来判断用户命令是否出错可以搭配try来使用。

    3.subprocess.Popen()


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

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

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

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

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

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

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

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

    4.获取命令执行后返回的结果:

    >>> import subprocess
    >>> com = subprocess.Popen('ifconfig',stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    >>> data = com.stdout.read()
    >>> data
    'enp3s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.41.8.24 netmask 255.255.252.0 broadcast 10.41.11.255 inet6 fe80::a993:220a:2a:a488 prefixlen 64 scopeid 0x20<link> ether 98:40:bb:20:25:b0 txqueuelen 1000 (Ethernet) RX packets 7041415 bytes 6473395772 (6.0 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 6470453 bytes 3937057528 (3.6 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 775007 bytes 96639605 (92.1 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 775007 bytes 96639605 (92.1 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vmnet1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.16.189.1 netmask 255.255.255.0 broadcast 172.16.189.255 inet6 fe80::250:56ff:fec0:1 prefixlen 64 scopeid 0x20<link> ether 00:50:56:c0:00:01 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1930 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 vmnet8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.16.150.1 netmask 255.255.255.0 broadcast 172.16.150.255 inet6 fe80::250:56ff:fec0:8 prefixlen 64 scopeid 0x20<link> ether 00:50:56:c0:00:08 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1923 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 wlp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.42.0.1 netmask 255.255.255.0 broadcast 10.42.0.255 inet6 fe80::3e8b:4ca8:230f:4f1e prefixlen 64 scopeid 0x20<link> ether 70:1c:e7:25:e8:47 txqueuelen 1000 (Ethernet) RX packets 394488 bytes 27416908 (26.1 MiB) RX errors 0 dropped 3 overruns 0 frame 0 TX packets 805283 bytes 1207252086 (1.1 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 '

  • 相关阅读:
    MySQL报错【innoDB is limited to rowlogging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED】
    【转】linux下解压命令大全
    java学习笔记
    【转】Linux安装MySQL tar文件
    Android部署及安装
    正则表达式各个符合含义
    [转]Linux下crontab命令的用法
    XTABLE学习笔记
    MySQL的mysqldump工具的基本用法
    java开发注意事项
  • 原文地址:https://www.cnblogs.com/nul1/p/8692717.html
Copyright © 2020-2023  润新知