subprocess
模块提供了多种方法来运行外部命令,并且可以捕获标准输出、标准错误等。以下是 subprocess.check_output
、stdout
参数、subprocess.run
和 subprocess.Popen
的区别和用途:
1. subprocess.check_output
-
用途 :运行命令并捕获标准输出(
stdout
)的输出。 -
行为:
-
如果命令成功(退出码为 0),它会返回标准输出的内容。
-
如果命令失败(退出码非 0),它会抛出一个
subprocess.CalledProcessError
异常。
-
-
优点:
-
简单易用,直接返回输出内容。
-
异常处理,方便调试。
-
-
示例:
try: output = subprocess.check_output(["echo", "Hello, World!"]) print(output.decode()) # 输出为 bytes,需要解码 except subprocess.CalledProcessError as e: print(f"Error: {e}")
2. stdout
参数
-
用途:
-
用于指定
subprocess
中标准输出的去向。 -
可以设置为:
-
subprocess.PIPE
:将输出捕获到管道中。 -
subprocess.DEVNULL
:丢弃输出。 -
sys.stdout
:将输出直接打印到控制台。
-
-
-
行为:
-
结合
subprocess.run
或subprocess.Popen
使用。 -
默认情况下,
stdout
会打印到控制台。
-
-
示例:
result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, text=True) print(result.stdout) # 捕获标准输出
3. subprocess.run
-
用途:运行命令并等待其完成。
-
行为:
-
返回一个
subprocess.CompletedProcess
对象。 -
默认情况下,标准输出和标准错误会打印到控制台。
-
可以通过参数(如
stdout
、stderr
、capture_output
等)控制输出和错误的处理。
-
-
优点:
-
简洁且功能强大。
-
可以控制命令的执行方式。
-
-
示例:
# 默认输出到控制台 subprocess.run(["echo", "Hello, World!"]) # 捕获输出 result = subprocess.run(["echo", "Hello, World!"], stdout=subprocess.PIPE, text=True) print(result.stdout)
4. subprocess.Popen
-
用途:创建一个子进程并与其交互。
-
行为:
-
是
subprocess
模块的底层实现,提供了更多灵活性。 -
可以通过管道与子进程进行交互(例如
stdin
、stdout
、stderr
)。 -
需要手动调用
.wait()
等待子进程结束。
-
-
优点:
-
灵活性高,适合复杂的交互场景。
-
可以动态地与子进程交互。
-
-
示例:
# 创建子进程 process = subprocess.Popen(["echo", "Hello, World!"], stdout=subprocess.PIPE, text=True) # 与子进程交互 output = process.communicate()[0] print(output) # 等待子进程结束 process.wait()
总结对比
方法 | 输出捕获 | 异常处理 | 返回类型 | 灵活性 | 用途 |
---|---|---|---|---|---|
subprocess.check_output |
是 | 有 | 字节或字符串 | 最低 | 简单获取标准输出 |
stdout 参数 |
是 | 无 | 需通过上下文获取 | 中 | 结合其他方法使用 |
subprocess.run |
可选 | 无 | CompletedProcess |
中 | 通用命令执行 |
subprocess.Popen |
可选 | 无 | Popen 对象 |
最高 | 复杂交互场景 |
选择建议
-
如果只需要捕获输出并处理异常,使用
subprocess.check_output
。 -
如果需要更灵活的控制和交互,使用
subprocess.Popen
。 -
如果只需要简单运行命令,使用
subprocess.run
。
有时候你使用check能打印输出但是获取不到文本信息 就只能使用popen或者run的stderr
result = subprocess.run(
command,
check=True,
stderr=subprocess.PIPE,
text=True,
encoding='utf-8'
)
output = result.stderr
输入输出都要用这个去获取
那是因为他输出的不是在标准输出 是在stderr下