# -*- 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: 传递文件描述符给子进程。