功能:通过python执行操作系统的命令。(os模块中的os.system()也有类似的功能)
前提小知识:
在操作系统上,两个应用程序进程之间的内存数据一般是不能直接互相访问的(系统的安全机制)。
在python上执行系统命令,其实相当于用python打开一个新的进程,然后在新进程里执行系统命令。
这样,执行的结果因为不是python的进程内数据,正常是获取不了结果的。
但是subprocess模块提供了一个获取系统命令执行结果方法(subprocess.PIPE)。这样就可以取得结果了。
既然有了,那么我们用subprocess做什么呢?
python中,用subprocess来替换掉下面这列老的模块和方法。
+ os.system
+ os.spawn*
主要方法:
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的意思是这条命令直接交给系统取执行,不需要用列表。
```subprocess.call(*popenargs, timeout=None, **kwargs)
跟run()类似,是另一种写法。需要了解可以查询一下文档。- 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) # 打开一个新进程,在后台执行系统命令
.poll() 检查子进程是否结束,结束返回 return code。(正常结束return 0)
.wait() 等待子进程结束,等结束了返回return code
.terminate() 终止python程序所启动的进程。用SIGTERM停止,并不是强制结束。相当于os.kill(pid,'SIGTERM')
python import os import signal os.kill(pid, signal.SIGTERM)
kill() 杀死所启动的进程。命令cpu中断进程。用SIGKILL,强制结束进程。 相当于:
```python
import os
import signalos.kill(pid, signal.SIGKILL)
```communicate() 与启动的进程(run()或者Popen()执行中的进程)交互,发送数据到stdin,并从stdout接受输出,然后等待任务结束。