Python2/3 中执行外部命令(Linux)和程序(exe) -- 子进程模块 subprocess

subprocess 模块可以使 Python 执行外部命令(Linux)和程序(exe),并得到相应的输出结果,进一步处理。在 Python3.5 中,subprocess 模块取代了 os.system、os.spawn* 。该模块很好地体现了 Python 胶水语言的特性,丰富了 Python 的拓展能力,故本文接下来主要介绍 subprocess 模块的用法,并简单说明在 Python2/3 中的使用区别。

 

速查表

Python2

Python3.5

subprocess.call(...)

subprocess.run(...)

subprocess.check_call(...)

subprocess.run(..., check=True)

subprocess.check_output(...)

subprocess.run(..., check=True, stdout=PIPE).stdout

subprocess.Popen(...)

subprocess.Popen(...)

通过上表可以看到,在 Python2 中 subprocess 模块共有三个函数 call、check_call、check_output 和一个类 Popen ,本质上这三个函数都是基于类 Popen 的封装,可以更简单地执行程序和获得输出。而在 Python3.5 中,三个函数可以通过 run 函数和参数设置来使用,同时这三个函数也可以在 Python3.5 中使用。

 

执行外部命令和程序

  1 import subprocess
  2 subprocess.call(["ls", "-l"])
  3 subprocess.call("ls -l", shell=True)
  4 subprocess.call("ffmpeg.exe -i test3.mp4 test.avi", shell=True)

前两个 call() 执行了查看当前目录的命令,第三个 call() 调用了 ffmpeg.exe 程序,对 test3.mp4 进行转码,生成 test.avi 。call() 函数默认接收拆分命令的列表,执行成功后,返回值 returncode 为0,失败返回1。当参数 shell=True 时,接收字符串,运行 shell,通过 shell 解释字符串,执行外部命令和程序。

 

添加错误处理的执行

  1 subprocess.check_call("exit 1", shell=True)

image

check_call() 函数与 call() 函数用法相似。但当返回值不为0时,会抛出 subprocess.CalledProcessError 异常。

 

获取输出的执行

  1 subprocess.check_output("ls -t | head -n 4", shell=True)

check_output() 函数与 check_call() 函数用法相似。但会返回执行的输出结果,以 bytes 序列接收,在 Python3 中可进行相应的解码 decode() 成字符串 str 序列,再进一步处理。该样例返回当前目录下按时间排序的前四个文件的详细信息。

 

需求化的执行

  1 child1 = subprocess.Popen("ls -t", shell=True, stdout=subprocess.PIPE)
  2 child2 = subprocess.Popen("head -n 4", shell=True, stdin=child1.stdout, stdout=subprocess.PIPE)
  3 outs, errs = child2.communicate()

Popen() 类创建并执行子进程。通过参数 stdin, stdout, stderr 改变标准输入、标准输出、标准错误,使用 subprocess.PIPE 初始化参数,创建缓存区,传递文本流,实现 Shell 管道功能。通过 communicate() 方法阻塞父进程,获取子进程执行结果,以 bytes 序列返回输出和错误的元组。

还可通过下列方法,操作子进程,获取相关信息:

  • Popen.wait():阻塞父进程,等待子进程终止。返回属性 returncode 。
  • Popen.poll():检查子进程状态。返回属性 returncode 。
  • Popen.kill():杀死子进程。
  • Popen.pid:获取子进程的进程ID。
  • Popen.returncode:获取子进程的返回码。

 

官方文档

Python3中的subprocess

Python2中的subprocess

posted @ 2018-01-13 23:14  sherlockChen  阅读(1532)  评论(0编辑  收藏  举报