别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

  • stackoverflow

  • Flask

  • 全栈之路

    • 基础篇

    • 进阶篇

    • 面向对象

    • 网络编程

    • 操作系统

    • 标准库

      • Python 标准库系列之 collections 模块
      • Python 标准库系列之 configparser 模块
      • Python 标准库系列之 datetime 模块
      • Python 标准库系列之 hashlib 模块
      • Python 标准库系列之模块介绍
      • Python 标准库系列之 json 模块
      • Python 标准库系列之 logging 模块
      • Python 标准库系列之 os 模块
      • Python 标准库系列之 random 模块
      • Python 标准库系列之 shutil 模块
      • Python 标准库系列之 subprocess 模块
        • 常用方法实例
        • subprocess.Popen()实例
        • 其他资料
        • 高级用法
          • Python2
          • Python3
      • Python 标准库系列之 sys 模块
      • Python 标准库系列之 tarfile 模块
      • Python 标准库系列之 time 模块
      • Python 标准库系列之 xml 模块
      • Python 标准库系列之 zipfile 模块
    • 第三方库

    • Python 全栈之路
  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • 全栈之路
  • 标准库
佚名
2020-05-23
目录

Python 标准库系列之 subprocess 模块

This module allows you to spawn processes, connect to their input/output/error pipes, and obtain their return codes.

# 常用方法实例

call()

执行命令,并返回状态码,状态码0代表命令执行成功,其他的都表示命令执行不成功

>>> ret = subprocess.call(["ls", "-l"], shell=False)
total 4
-rw-r--r-- 1 root root 172 May 25 21:21 file.conf
>>> ret
0
1
2
3
4
5

另一种执行方式

# shell=True表示调用原生的shell命令去执行
>>> ret = subprocess.call("ls -l", shell=True)
total 4
-rw-r--r-- 1 root root 172 May 25 21:21 file.conf
>>> ret
0
1
2
3
4
5
6

check_call()

执行命令,如果执行状态码是 0,则返回 0,否则抛异常

# 执行一个正确的命令就会返回执行结果和状态码
>>> subprocess.check_call(["ls", "-l"])
total 4
-rw-r--r-- 1 root root 172 May 25 21:21 file.conf
0
# 如果执行的是一个错误的命令,那么就会返回错误信息
>>> subprocess.check_call(["ls", "a"])  
ls: cannot access a: No such file or directory
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/subprocess.py", line 505, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['ls', 'a']' returned non-zero exit status 2
1
2
3
4
5
6
7
8
9
10
11
12
13

check_output()

执行命令,如果状态码是 0,则返回执行结果,否则抛异常

# 执行成功就把执行的结果赋值给变量V
>>> V = subprocess.check_output("python -V", shell=True)
# 执行错误的命令就会输出异常
>>> subprocess.check_output("pasas", shell=True)
'pasas' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python35\lib\subprocess.py", line 629, in check_output
    **kwargs).stdout
  File "C:\Python35\lib\subprocess.py", line 711, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'pasas' returned non-zero exit status 1
1
2
3
4
5
6
7
8
9
10
11
12
13

注意:在执行命令的时候,shell默认等于True,等于True的时候,括号内的命令是一行的字符串;如果shell等于False,那么[]内的字符串就是命令的一个元素,执行的时候会把[]内的字符串拼接起来执行。

subprocess.Popen()

call()、check_call()、check_output()默认内部调用的都是subprocess.Popen(),而subprocess.Popen()则用于执行更复杂的系统命令。

参数

参数 说明
stdin 标准输入
stdout 标准输出
stderr 错误句柄
cwd 用于设置子进程的当前目录
env 用于指定子进程的环境变量。如果 env = None,子进程的环境变量将从父进程中继承

执行普通命令

>>> subprocess.Popen("Python -V", shell=True)
<subprocess.Popen object at 0x0000025C97233C88>
# Python 3.5.1是输出出来的结果
>>> Python 3.5.1
1
2
3
4

执行命令分为两种:

  1. 输入即可得到输出,如:ifconfig
  2. 输入进行某交互式环境,依赖再输入,如:python
>>> import subprocess
# 先进入'/tmp'目录,然后在创建subprocess文件夹,shell=True可有可无
>>> subprocess.Popen("mkdir subprocess", shell=True, cwd='/tmp',)
<subprocess.Popen object at 0x7f267cc3d390>
>>> import os
>>> os.system("ls /tmp")
subprocess
1
2
3
4
5
6
7

# subprocess.Popen()实例

# 导入subprocess模块
import subprocess

# 执行python命令,进入python解释器,stdin标准输入、stdout标准输出、stderr错误输出,universal_newlines=True自动输入换行符
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

# 执行标准输入,write后面是输入的命令
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)")
# 输入之后关闭
obj.stdin.close()

# 读取标准输出的内容,赋值给cmd_out对象
cmd_out = obj.stdout.read()
# 关闭标准输出
obj.stdout.close()

# 读取错误输出的内容,赋值给cmd_error对象
cmd_error = obj.stderr.read()

# 关闭错误输出
obj.stderr.close()

# 输出内容
print(cmd_out)
print(cmd_error)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

执行结果

C:\Python35\python.exe F:/Python_code/sublime/Week5/Day02/sub.py
1
2



Process finished with exit code 0
1
2
3
4
5
6
7
# 导入subprocess模块
import subprocess

# 执行python命令,进入python解释器,stdin标准输入、stdout标准输出、stderr错误输出,universal_newlines=True自动输入换行符
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

# 执行两条命令
obj.stdin.write("print(1)\n")
obj.stdin.write("print(2)")

# communicate把错误输出或者标准输出的内容赋值给out_error_list对象,如果有错误就赋值错误输出,否则就复制标准输出
out_error_list = obj.communicate()

# 输出out_error_list对象的内容
print(out_error_list)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

执行结果

C:\Python35\python.exe F:/Python_code/sublime/Week5/Day02/sub.py
('1\n2\n', '')

Process finished with exit code 0
1
2
3
4
# 导入subprocess模块
import subprocess

# 执行python命令,进入python解释器,stdin标准输入、stdout标准输出、stderr错误输出,universal_newlines=True自动输入换行符
obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)


# 直接执行print("hello")命令,然后把错误或者正确的结果赋值给out_error_list对象
out_error_list = obj.communicate('print("hello")')

# 输出out_error_list对象的内容
print(out_error_list)
1
2
3
4
5
6
7
8
9
10
11
12

执行结果

C:\Python35\python.exe F:/Python_code/sublime/Week5/Day02/sub.py
('hello\n', '')

Process finished with exit code 0
1
2
3
4

# 其他资料

Python 之系统交互(subprocess) - 云游道士 - 博客园 (opens new window)

# 高级用法

今天在使用的时候想要实现一个“流输出”,即类似于一个输出为长耗时的操作,需要把结果实时打印在屏幕上:

# Python2

from subprocess import Popen, PIPE

def cust_popen(_cmd):
    """
    流输出结果
    :param _cmd:
    :return:
    """
    if isinstance(_cmd, list):
        shell = False
    else:
        shell = True
    p = Popen(_cmd, stdout=PIPE, shell=shell, bufsize=1)
    with p.stdout:
        for line in iter(p.stdout.readline, b''):
            print(line),  # for py2
    p.wait()  # wait for the subprocess to exit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

iter() 用于一旦行被写入工作区,则立即读取其内容;

# Python3

#!/usr/bin/env python3
from subprocess import Popen, PIPE

with Popen(["cmd", "arg1"], stdout=PIPE, bufsize=1,
           universal_newlines=True) as p:
    for line in p.stdout:
        print(line, end='')
1
2
3
4
5
6
7

与 Python 2 不同,Python 2 照原样输出子进程的字节串。 Python 3 使用文本模式(使用 locale.getpreferredencoding(False) 编码对 cmd 的输出进行解码)。

来源参见python - Read streaming input from subprocess.communicate() - StackOverflow (opens new window)

编辑 (opens new window)
#编码#面向对象
上次更新: 2024-07-23, 01:00:43
Python 标准库系列之 shutil 模块
Python 标准库系列之 sys 模块

← Python 标准库系列之 shutil 模块 Python 标准库系列之 sys 模块→

最近更新
01
2025 面试记录
05-28
02
提升沟通亲和力的实用策略
03-26
03
工作
07-15
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式