• Python Linux系统管理之Python中执行外部命令


    一、简介

    有很多需求需要在Python中执行shell命令、启动子进程,并捕获命令的输出和退出状态码,类似于Java中的Runtime类库。本文将介绍subprocess模块的定位,然后介绍subprocess模块提供的便利函数,最后介绍Popen这个类的使用方法。

    二、subprocess模块的使用

    1、call

    call函数的定义如下:

    subprocess.call(args,*,stdin=None,stout=None,stderr=None,shell=False)

    call函数将允许由args参数制定的命令直到命令结束。call函数的返回值是命令的退出状态码,工程师可以通过退出状态码判断命令是否执行成功。如下所示:

    In [1]: import subprocess
    In [2]: subprocess.call([‘ls’,’-l’])
    total 8
    -rw-r–r–. 1 root root 0 Sep 24 10:52 1.txt

    -rw-r–r–. 1 root root 0 Sep 24 10:52 2.txt

    -rw-r–r–. 1 root root 3736 Sep 24 10:51 demo.tar.gz

    -rw-r–r–. 1 root root 929 Sep 24 10:52 demo.zip

    Out[2]: 0

    In [3]: subprocess.call(“exit 1”,shell = True)

    Out[3]: 1

    注:如果设置shell=True,Python会先运行一个shell,再用shell解释字符串,而不是传递一个列表。

    2、check_call

    check_all与call类似,只是遇到异常情况返回的形式不同。如果命令执行成功,下面会返回0;如果命令执行失败,它会抛出subprocess.CalledProcessError异常,相关案例如下所示:

    In [5]: subprocess.check_call([“ls”,”-l”])
    total 8
    -rw-r–r–. 1 root root 0 Sep 24 10:52 1.txt
    -rw-r–r–. 1 root root 0 Sep 24 10:52 2.txt

    -rw-r–r–. 1 root root 3736 Sep 24 10:51 demo.tar.gz

    -rw-r–r–. 1 root root 929 Sep 24 10:52 demo.zip

    Out[5]: 0

    In [6]: subprocess.check_call(“exit 1”,shell = True)

    —————————————————————————

    CalledProcessError Traceback (most recent call last)

    <ipython-input-6-f13e6678cc55> in <module>()

    —-> 1 subprocess.check_call(“exit 1”,shell = True)

    /usr/local/lib/python3.7/subprocess.py in check_call(*popenargs, **kwargs)

    326 if cmd is None:

    327 cmd = popenargs[0]

    –> 328 raise CalledProcessError(retcode, cmd)

    329 return 0

    330

    CalledProcessError: Command ‘exit 1’ returned non-zero exit status 1.

    3、check_output

    从上面的输出结果可以看到,call和check_call函数直接将命令的输出结果输出到命令行终端,这种返回结果的形式很有可能是你不想要的。在实际工作过程中,一般会对获取命令的结果进行进一步处理,或者将命令的输出打印到日志文件中。如下所示:

    In [1]: import subprocess
    In [2]: output = subprocess.check_output([‘df’,’-h’])
    In [3]: print(output)
    b’Filesystem Size Used Avail Use{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} Mounted on /dev/mapper/centos-root 50G 1.7G 49G 4{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} / devtmpfs 1.9G 0 1.9G 0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /dev tmpfs 1.9G 0 1.9G 0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /dev/shm tmpfs 1.9G 12M 1.9G 1{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /run tmpfs 1.9G 0 1.9G 0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /sys/fs/cgroup /dev/mapper/centos-home 106G 246M 105G 1{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /home /dev/sda1 1014M 184M 831M 19{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /boot tmpfs 378M 0 378M 0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /run/user/0 ’

    In [4]: lines = output.split(b’ ’)

    In [5]: lines

    Out[5]:

    [b’Filesystem Size Used Avail Use{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} Mounted on’,

    b’/dev/mapper/centos-root 50G 1.7G 49G 4{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /’,

    b’devtmpfs 1.9G 0 1.9G 0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /dev’,

    b’tmpfs 1.9G 0 1.9G 0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /dev/shm’,

    b’tmpfs 1.9G 12M 1.9G 1{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /run’,

    b’tmpfs 1.9G 0 1.9G 0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /sys/fs/cgroup’,

    b’/dev/mapper/centos-home 106G 246M 105G 1{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /home’,

    b’/dev/sda1 1014M 184M 831M 19{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /boot’,

    b’tmpfs 378M 0 378M 0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b} /run/user/0′,

    b”]

    In [6]: for line in lines[1:-1]:

    …: if line:

    …: print(line.split()[-2])

    …:

    b’4{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b}’

    b’0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b}’

    b’0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b}’

    b’1{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b}’

    b’0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b}’

    b’1{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b}’

    b’19{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b}’

    b’0{815ac408a99669c280d890a3c1592527154068adde55fb55fc5b84dc9fd9f61b}’

    如果想要捕捉退出状态码,可以通过抛出的subprocess.CalledProcessError异常。

    import subprocess
    try:
    output = subprocess.check_output(‘cmd’,’arg1′ ,’arg2′)
    except subprocess.CalledProcessError as e:

    output = e.output

    code = e.returncode

    默认情况下,check_output命令只会捕捉命令的标准输出。如果想捕捉命令的错误输出,需要将错误输出重定向到标准输出。如下所示:

    output = subprocess.check_output([‘cmd’,’arg1′ ,’arg2′],stderr= subprocess.STDOUT)
  • 相关阅读:
    EventHandler 与常见的.Net预定义委托
    Consistent Hashing算法及相关技术
    全序, 分布式一致性的本质
    Paxos Made Simple
    Strong Consistency, 强一致性技术概述
    Chubby lock service for looselycoupled distributed systems
    AntiEntropy Protocols
    Mesos: A Platform for FineGrained Resource Sharing in the Data Center
    Spark A FaultTolerant Abstraction for InMemory Cluster Computing
    Vector Clocks, 时间向量
  • 原文地址:https://www.cnblogs.com/liujunjun/p/13475477.html
Copyright © 2020-2023  润新知