• python执行系统命令的方法:os.system(), os.popen(), subprocess.Popen()


    一、os.system方法

    1、返回值

    执行操作系统的命令,将结果输出到屏幕,只返回命令执行状态(0:成功,非 0 : 失败)

    >>> result = os.system('pwd')
    /root
    >>> result
    0

    2、阻塞

    在执行os.system函数的时候通常会阻塞它的调用者,等待所启动的命令行程序退出。

    Linux平台上 只需要在命令末尾加上shell后台运算符&即可。

     

    二、os.popen方法

    执行操作系统的命令,会将结果保存在file对象当中,可以用read()、readlines()等方法读取出来

    import os
    result = os.popen('cat /etc/passwd')
    print(result.read())

    三、commands模块

    关于 commands 的说明:

    1. python 3.0 之后移除此命令,使用 subprocess代替;
    2. python 3.x 使用 subprocess 创建一个新进程;

    四、subprocess模块

    Subprocess是一个功能强大的子进程管理模块,是替换

    • os.system
    • os.spawn*
    • os.popen*
    • popen2.*
    • commands.*

    等方法的一个模块。

    当执行命令的参数或者返回中包含了中文文字,那么建议使用subprocess。

    1、subprocess.run()

    1.1、 python 解析则传入命令的每个参数的列表

    >>> import subprocess
    >>> subprocess.run(["df",'-h'])
    Filesystem Size Used Avail Use% Mounted on
    /dev/vda3 196G 34G 163G 17% /
    devtmpfs 906M 0 906M 0% /dev
    tmpfs 920M 22M 899M 3% /dev/shm
    tmpfs 920M 67M 854M 8% /run
    tmpfs 920M 0 920M 0% /sys/fs/cgroup
    /dev/vda1 497M 154M 344M 31% /boot
    tmpfs 184M 40K 184M 1% /run/user/0
    CompletedProcess(args=['df', '-h'], returncode=1)
    >>>

    1.2、需要交给Linux shell自己解析,则:传入命令字符串,shell=True

    >>> subprocess.run("df -h | grep /dev/vda3",shell=True)
    /dev/vda3 196G 34G 163G 17% /
    CompletedProcess(args='df -h | grep /dev/vda3', returncode=0)
    >>>

    2、subprocess.call()

    执行命令,返回命令的结果和执行状态,0或者非0

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

    总用量 28
    -rw-r--r-- 1 root root   0 616 10:28 1
    drwxr-xr-x 2 root root 4096 622 17:48 _1748
    -rw-------. 1 root root 1264 428 20:51 anaconda-ks.cfg
    drwxr-xr-x 2 root root 4096 525 14:45 monitor
    -rw-r--r-- 1 root root 13160 5月  9 13:36 npm-debug.log
    # 命令执行状态
    >>> res
    0
     

    3、subprocess.check_call()

    执行命令,返回结果和状态,正常为0 ,执行错误则抛出异常

    3.1、正常情况

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

    总用量 28
    -rw-r--r-- 1 root root   0 616 10:28 1
    drwxr-xr-x 2 root root 4096 622 17:48 _1748
    -rw-------. 1 root root 1264 428 20:51 anaconda-ks.cfg
    drwxr-xr-x 2 root root 4096 525 14:45 monitor
    -rw-r--r-- 1 root root 13160 5月  9 13:36 npm-debug.log
    0

    3.2、错误情况

    >>> result=subprocess.check_call(["lm","-l"])
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/python3/lib/python3.6/subprocess.py", line 286, in check_call
    retcode = call(*popenargs, **kwargs)
    File "/usr/local/python3/lib/python3.6/subprocess.py", line 267, in call
    with Popen(*popenargs, **kwargs) as p:
    File "/usr/local/python3/lib/python3.6/subprocess.py", line 707, in __init__
    restore_signals, start_new_session)
    File "/usr/local/python3/lib/python3.6/subprocess.py", line 1326, in _execute_child
    raise child_exception_type(errno_num, err_msg)
    FileNotFoundError: [Errno 2] No such file or directory: 'lm'

     

    4、subprocess.getstatusoutput()

    接受字符串形式的命令,返回 一个元组形式的结果,第一个元素是命令执行状态,第二个为执行结果

    4.1、执行正确

    >>> result = subprocess.getstatusoutput("pwd")
    >>> result
    (0, '/root')

    4.2、执行错误

    >>> result = subprocess.getstatusoutput("pwdd")
    >>> result
    (127, '/bin/sh: pwdd: command not found')

     

    5、subprocess.getoutput()

    接受字符串形式的命令,返回执行结果

    5.1、执行命令正常

    >>> result = subprocess.getoutput("pwd")
    >>> result
    '/root'

    5.2、执行命令出错

    >>> result = subprocess.getoutput("pwdd")
    >>> result
    '/bin/sh: pwdd: command not found'
    >>>

    6、subprocess.check_output()

    6.1、执行命令正常,以字节形式返回

    >>> result = subprocess.check_output("pwd")
    >>> result
    b'/root\n' # 结果以字节形式返回

    6.2、执行命令出错,抛出异常

    >>> result = subprocess.check_output("pwdd")
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/python3/lib/python3.6/subprocess.py", line 336, in check_output
    **kwargs).stdout
    File "/usr/local/python3/lib/python3.6/subprocess.py", line 403, in run
    with Popen(*popenargs, **kwargs) as process:
    File "/usr/local/python3/lib/python3.6/subprocess.py", line 707, in __init__
    restore_signals, start_new_session)
    File "/usr/local/python3/lib/python3.6/subprocess.py", line 1326, in _execute_child
    raise child_exception_type(errno_num, err_msg)
    FileNotFoundError: [Errno 2] No such file or directory: 'pwdd'
    >>>

     
    import subprocess
    res = subprocess.Popen('cat /etc/passwd', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # 使用管道
    # print res.stdout.read()  # 标准输出
    for line in res.stdout.readlines():
        print line
    res.stdout.close()         # 关闭

     7、subprocess.Popen()

    其实前面subprocess使用的方法,都是对subprocess.Popen的封装,下面我们就来看看这个Popen方法。

    7.1、stdout

    标准输出

    >>> res = subprocess.Popen("ls /tmp/yum.log", shell=True, stdout=subprocess.PIPE) # 使用管道

    >>> res.stdout.read()  # 标准输出
    b'/tmp/yum.log\n'
    res.stdout.close()  # 关闭

     

    7.2、stderr

    标准错误

    >>> import subprocess

    >>> res = subprocess.Popen("lm -l",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    # 标准输出为空
    >>> res.stdout.read()
    b''
    #标准错误中有错误信息
    >>> res.stderr.read()
    b'/bin/sh: lm: command not found\n'

    注意:上面的提到的标准输出都为啥都需要等于subprocess.PIPE,这个又是啥呢?原来这个是一个管道,这个需要画一个图来解释一下

    7.3、poll()

    定时检查命令有没有执行完毕,执行完毕后返回执行结果的状态,没有执行完毕返回None

    >>> res = subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    >>> print(res.poll())
    None
    >>> print(res.poll())
    None
    >>> print(res.poll())
    0

    7.4、wait()

    等待命令执行完成,并且返回结果状态

    >>> obj = subprocess.Popen("sleep 10;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

    >>> obj.wait()
    # 中间会一直等待
    0
     
     

    7.5、terminate()

    结束进程

    import subprocess

    >>> res = subprocess.Popen("sleep 20;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    >>> res.terminate() # 结束进程
    >>> res.stdout.read()
    b''

    7.6、pid

    获取当前执行子shell的程序的进程号

    import subprocess

    >>> res = subprocess.Popen("sleep 5;echo 'hello'",shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    >>> res.pid # 获取这个linux shell 的 进程号
    2778
  • 相关阅读:
    使用 Prism.js 实现代码高亮
    Win10系统如何删除网络及修改网络名称
    CRT和PEM格式证书转换
    CentOS如何修改主机名
    crt格式证书转换为pem格式
    CentOS安装wget命令
    自适应(响应式)网页中的几个关键分辨率
    java中的I/O流学习(1)
    有种心态,我不知该如何表达
    java学习笔记—Scanner
  • 原文地址:https://www.cnblogs.com/superbaby11/p/15560994.html
Copyright © 2020-2023  润新知