第六章 常用模块(8):python常用模块(执行系统命令的模块:subprocess模块)

功能:通过python执行操作系统的命令。(os模块中的os.system()也有类似的功能)

前提小知识:
在操作系统上,两个应用程序进程之间的内存数据一般是不能直接互相访问的(系统的安全机制)。
在python上执行系统命令,其实相当于用python打开一个新的进程,然后在新进程里执行系统命令。
这样,执行的结果因为不是python的进程内数据,正常是获取不了结果的。
但是subprocess模块提供了一个获取系统命令执行结果方法(subprocess.PIPE)。这样就可以取得结果了。

既然有了,那么我们用subprocess做什么呢?
python中,用subprocess来替换掉下面这列老的模块和方法。
+ os.system
+ os.spawn*

主要方法:

  1. subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs) 执行系统命令,并且等待执行结束才继续进行后面的代码。 返回命令执行结果的对象。 例:
    ```python
    import subprocess

    # 一般命令写法:用列表输入命令
    res1 = subprocess.run(['ipconfig','/all'],stderr=subprocess.PIPE,stdout=subprocess.PIPE,check=True) # 命令用空格分成列表的不同元素
    # 执行'ipconfig /all',执行结果报错赋值给stderr,正常执行结果赋值给stdout,check=True表示如果执行结果报错,这行python命令也报错

    # 取得返回结果
    print(res1.stdout) # 输出结果,类型时bytes。
    print(res1.stdout.decode('shift-jis')) # 需要对bytes进行decode()。decode编码需要用系统的默认编码(这个系统是日文的所以是shift-jis)

    print(res1.stderr) # 输出报错的内容(没错是空值),类型是bytes

    # 涉及到管道符号'|'时的命令需要这样写:不要用列表,并且加上option:shell=True
    res2 = subprocess.run('df -h|grep disk1',stderr=subprocess.PIPE,stdout=subprocess.PIPE,shell=True) # shell=True的意思是这条命令直接交给系统取执行,不需要用列表。
    ```

  2. subprocess.call(*popenargs, timeout=None, **kwargs)
    跟run()类似,是另一种写法。需要了解可以查询一下文档。

  3. subprocess.Popen()
    打开一个新的进程,在后台执行命令。
    run()和call()本质上都是封装了Popen()。功能都是它实现的,所以很重要!
    常用参数:
    • args:系统命令(linux,Unix:shell; Windows:dos命令),可以是字符串或者序列类型(list,tuple)
    • stdin,stdout,stderr:分别表示程序的标准输入,标准输出,错误
    • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object--python的函数),他将在子进程运行之前被调用
    • shell:在run()例中说明了
    • cwd:用于设置子进程的额当前目录
    • env:用于指定子进程的环境变量。如果env=None,子进程的环境变量将从父进程中继承。
      思考,下面两条命令的区别:
    import subprocess
    
    a = subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE)  # 等待系统命令执行完后继续
    b = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)  # 打开一个新进程,在后台执行系统命令
  4. .poll() 检查子进程是否结束,结束返回 return code。(正常结束return 0)

  5. .wait() 等待子进程结束,等结束了返回return code

  6. .terminate() 终止python程序所启动的进程。用SIGTERM停止,并不是强制结束。相当于os.kill(pid,'SIGTERM')
    python import os import signal os.kill(pid, signal.SIGTERM)

  7. kill() 杀死所启动的进程。命令cpu中断进程。用SIGKILL,强制结束进程。 相当于:
    ```python
    import os
    import signal

    os.kill(pid, signal.SIGKILL)
    ```

  8. communicate() 与启动的进程(run()或者Popen()执行中的进程)交互,发送数据到stdin,并从stdout接受输出,然后等待任务结束。

猜你喜欢

转载自www.cnblogs.com/py-xiaoqiang/p/11110885.html