subprocess 模块

发布于:2025-04-21 ⋅ 阅读:(17) ⋅ 点赞:(0)
# -*- coding: utf-8 -*-
import subprocess
#
# subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None,
#                capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None,
#                errors=None, text=None, env=None, universal_newlines=None, **other_popen_kwargs)


# 执行windows命令,当然也可以运行linux命令
# 使用字符串形式运行 mkdir 命令

# args 参数
# 类型: list 或 str
# 作用: 指定要执行的命令及其参数。

# 1. 使用列表形式 (list)
# 当 args 是一个列表时,列表的第一个元素是要执行的命令,后续元素是传递给该命令的参数
# #创建一个文件夹,shell命令,文件夹名称为new_folder
subprocess.run("mkdir new_folder", shell=True)


# 2.指定子进程的标准输入来源
# 在 Python 的 subprocess 模块中,stdin 是一个关键参数,用于控制子进程的标准输入流。它可以接受以下几种类型的值:
# subprocess.PIPE:
# 这是告诉 Python 你想通过管道捕获子进程的标准输入流。
# 当你设置 stdin=subprocess.PIPE 并且使用 input 参数时,Python 会将 input 参数的内容发送到子进程的标准输入。
# 注意:不能同时使用 stdin=subprocess.PIPE 和 input 参数,因为它们的作用重叠。
# 文件对象:
# 你可以传递一个已经打开的文件对象给 stdin 参数,这样子进程就会从该文件读取其输入数据。
# 这对于需要处理大量数据或者希望从文件读取输入的情况非常有用。
# 其他可执行文件或命令的标准输出:
# 你也可以将另一个子进程的输出直接作为当前子进程的输入,这通常通过管道实现。
# 创建一个示例文件 example.txt,并写入一些文本内容
with open("example.txt", "w", encoding="utf-8") as file:
    file.write("hello world\nthis is a test\nhello again\n")

# 使用 findstr 命令过滤包含 "hello" 的行
with open("example.txt", "r", encoding="utf-8") as file:
    result = subprocess.run(
        ["findstr", "hello"],  # Windows 上的命令,用于搜索匹配的行
        stdin=file,  # 设置 stdin 为打开的文件对象
        stdout=subprocess.PIPE,  # 捕获标准输出
        stderr=subprocess.PIPE   # 捕获标准错误
    )

# 打印捕获的输出
print("标准输出:")
print(result.stdout.decode('utf-8').strip())  # 打印标准输出内容

print("\n标准错误:")
print(result.stderr.decode('utf-8').strip())  # 打印标准错误内容

# 3.input 参数的作用
# input 参数:
# 它允许你直接向子进程的标准输入发送数据。
# 如果设置了 input 参数,则必须确保子进程可以从标准输入读取数据(例如通过管道或文件)。
# 如果 input=None,则表示不向子进程的标准输入发送任何数据。
# 与 stdin 的关系:
# 如果你设置了 input 参数,则不能同时设置 stdin=subprocess.PIPE,因为它们的功能是重复的。
# 如果你需要从文件或其他来源提供输入,请使用 stdin 参数
# 使用 findstr 命令查找包含 "hello" 的行
result = subprocess.run(
    ["findstr", "hello"],  # Windows 上的命令,用于搜索匹配的行
    input="hello world\nthis is a test\nhello again\n",  # 向子进程发送多行文本
    text=True,  # 标准输入和输出作为文本处理
    stdout=subprocess.PIPE,  # 捕获标准输出
    stderr=subprocess.PIPE   # 捕获标准错误
)

# 打印捕获的输出
print("标准输出:")
print(result.stdout.strip())  # 打印标准输出内容

print("\n标准错误:")
print(result.stderr.strip())  # 打印标准错误内容

# 4.stdout=None 的作用
# 默认行为
# 如果 stdout=None(默认值),子进程的标准输出会直接打印到父进程的终端(即继承父进程的标准输出)。
# 也就是说,子进程的输出不会被捕获或存储,而是直接显示在控制台中
# 使用 findstr 命令查找包含 "hello" 的行
result = subprocess.run(
    ["findstr", "hello"],  # Windows 上的命令,用于搜索匹配的行
    input="hello world\nthis is a test\nhello again\n",  # 向子进程发送多行文本
    text=True,  # 标准输入和输出作为文本处理
    stdout=None,  # 不捕获标准输出,直接打印到控制台
    stderr=subprocess.PIPE  # 捕获标准错误
)

# 打印捕获的输出
print("标准错误:")
print(result.stderr.strip())  # 打印标准错误内容

# 5.stderr=None 的作用
# 默认行为
# 如果 stderr=None(默认值),子进程的标准错误会直接打印到父进程的终端(即继承父进程的标准错误)。
# 子进程的错误信息不会被捕获或存储,而是直接显示在控制台中。
# 使用 findstr 命令查找包含 "hello" 的行
result = subprocess.run(
    ["findstr", "nonexistent"],  # Windows 上的命令,用于搜索不存在的字符串
    input="hello world\nthis is a test\nhello again\n",  # 向子进程发送多行文本
    text=True,  # 标准输入和输出作为文本处理
    stdout=subprocess.PIPE,  # 捕获标准输出
    stderr=None  # 不捕获标准错误,直接打印到控制台
)

# 打印捕获的输出
print("标准输出:")
print(result.stdout.strip())  # 打印标准输出内容

# 6.capture_output=True:
# 自动捕获子进程的标准输出和标准错误。
# 等价于手动设置 stdout=subprocess.PIPE 和 stderr=subprocess.PIPE。
# capture_output=False(默认值):
# 不捕获子进程的标准输出和标准错误。
# 子进程的输出和错误信息会直接打印到父进程的终端
# 使用 capture_output=False 不捕获输出
result = subprocess.run(
    ["findstr", "hello"],  # Windows 上的命令,用于搜索匹配的行
    input="hello world\nthis is a test\nhello again\n",  # 向子进程发送多行文本
    text=True,  # 标准输入和输出作为文本处理
    capture_output=False  # 不捕获标准输出和标准错误
)

# result.stdout 和 result.stderr 都为空
print("标准输出和标准错误未被捕获")

# 7.shell=False 的详细说明
# 默认行为
# shell=False(默认值)表示直接运行指定的命令,而不是通过系统的 shell。
# 这意味着你需要将命令及其参数作为列表传递给 subprocess.run。
# 使用 shell=False 更安全,因为它避免了潜在的命令注入攻击

# 8.cwd 参数的作用
# cwd=None(默认值):
# 子进程在 Python 脚本的当前工作目录中运行。
# 当前工作目录通常是指运行 Python 脚本时所在的目录。
# cwd=指定目录:
# 子进程会在指定的目标目录中运行。
# 这对于需要访问特定目录中的文件或资源的场景非常有用。


# 9.timeout 参数的作用
# timeout=None(默认值):
# 表示没有超时限制,子进程可以无限期运行。
# 这是默认行为,适用于你希望子进程一直运行直到完成的场景。
# timeout=秒数:
# 设置子进程的最大运行时间(以秒为单位)。
# 如果子进程在指定时间内没有完成,Python 会抛出 subprocess.TimeoutExpired 异常。

# 10.check 参数的作用
# check=False(默认值):
# 即使子进程的退出码是非零值,也不会抛出异常。
# 这意味着你需要手动检查子进程的退出状态(通过 result.returncode)来判断它是否成功运行。
# check=True:
# 如果子进程的退出码是非零值,会自动抛出 subprocess.CalledProcessError 异常。
# 这种方式适用于你希望直接捕获错误并处理的情况。

# 11.encoding 参数的作用
# encoding=None(默认值):
# 不指定编码格式,默认以字节形式处理输入和输出。
# 如果同时设置了 text=True 或 universal_newlines=True,则默认使用系统默认的编码(通常是 locale.getpreferredencoding(False))。
# encoding=指定编码:
# 指定子进程的输入、输出和错误信息的编码格式。
# 常见的编码格式包括 "utf-8"、"ascii"、"latin1" 等。

# 12.errors 参数的作用
# errors=None(默认值):
# 如果未指定 errors 参数,则默认行为取决于 encoding 和 text 的设置。
# 如果设置了 encoding 或 text=True,则默认使用 "strict" 模式,即遇到编码/解码错误时抛出异常。
# errors=指定模式:
# 指定如何处理编码或解码错误。
# 常见的模式包括:
# "strict":遇到错误时抛出 UnicodeError 异常(默认行为)。
# "ignore":忽略无法解码或编码的字符。
# "replace":用替代字符(如 ? 或 \ufffd)替换无法解码或编码的字符。
# 其他模式(如 "backslashreplace" 等):参见 Python 的 codecs 模块文档

# 13.text 参数的作用
# text=None(默认值):
# 如果未指定 text 参数,则默认以字节流形式处理子进程的输入和输出。
# 即使设置了 encoding,也不会自动将字节流解码为字符串。
# text=True:
# 启用文本模式,子进程的输入和输出将以字符串形式处理。
# 等价于设置 universal_newlines=True。
# 如果同时指定了 encoding 参数,则会使用指定的编码格式;否则,默认使用系统默认编码(通常是 locale.getpreferredencoding(False))。
# text=False:
# 明确禁用文本模式,子进程的输入和输出将以字节流形式处理

# 14.env 参数的作用
# env=None(默认值):
# 如果未指定 env 参数,子进程将继承父进程的环境变量。
# 这意味着子进程可以访问到启动它的Python脚本或命令行界面中所有的环境变量。
# env=自定义字典:
# 你可以提供一个字典来覆盖或扩展子进程的环境变量。
# 如果提供了 env 参数,那么子进程只会看到你在字典中定义的环境变量,除非你特意从父进程的环境变量中复制某些变量过来。
# 使用场景
# 修改特定环境变量: 当你需要为子进程设置或更改某些环境变量时,可以使用 env 参数。
# 隔离环境变量: 在某些情况下,可能需要确保子进程不受父进程环境中任何环境变量的影响,这时可以传递一个空字典 {} 或者只包含必要变量的新字典给 env 参数。

# 15.universal_newlines 参数的作用
# universal_newlines=None(默认值):
# 如果未指定 universal_newlines 参数,则默认以字节流形式处理子进程的输入和输出。
# 即使设置了 encoding,也不会自动将字节流解码为字符串。
# universal_newlines=True:
# 启用文本模式,子进程的输入和输出将以字符串形式处理。
# 如果同时指定了 encoding 参数,则会使用指定的编码格式;否则,默认使用系统默认编码(通常是 locale.getpreferredencoding(False))。
# universal_newlines=False:
# 明确禁用文本模式,子进程的输入和输出将以字节流形式处理。

# 16.**other_popen_kwargs 参数的作用
# **other_popen_kwargs:
# 这是一个可变关键字参数(var-keyword argument),允许你将任意数量的关键字参数传递给 subprocess.Popen。
# 它使得你可以使用 subprocess.run 中未直接暴露的 Popen 参数来配置子进程的行为。
# 常见的 subprocess.Popen 参数
# 以下是一些可以通过 **other_popen_kwargs 传递的常见参数:
# cwd: 设置子进程的工作目录。
# startupinfo: 在 Windows 上设置启动信息,例如隐藏命令行窗口。
# creationflags: 在 Windows 上设置创建标志,例如 CREATE_NEW_CONSOLE。
# preexec_fn: 在 Unix 系统上,在执行子进程之前调用的函数。
# restore_signals: 在 Unix 系统上,恢复默认信号处理。
# start_new_session: 在 Unix 系统上,启动一个新的会话并成为该会话的领导者。
# pass_fds: 传递文件描述符给子进程。

网站公告

今日签到

点亮在社区的每一天
去签到