news 2026/6/16 3:51:57

Python subprocess管理外部进程的完整实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python subprocess管理外部进程的完整实践

Python subprocess管理外部进程的完整实践

subprocess模块替代了os.system、os.popen等旧API。核心是Popen类,run和call是便捷封装。

Popen的基本用法:

import subprocess

proc = subprocess.Popen(['ls', '-la'], stdout=subprocess.PIPE)
output, errors = proc.communicate()
print(output.decode())

Popen启动子进程并立即返回。communicate等待子进程结束并收集输出。

run的便捷封装:

result = subprocess.run(['ls', '-la'], capture_output=True, text=True, check=True)
print(result.stdout)
print(result.returncode)

run等特子进程结束,返回CompletedProcess对象。capture_output=True自动捕获stdout和stderr。text=True以文本模式返回而非字节。

管道连接多个进程:

ls = subprocess.Popen(['ls', '-la'], stdout=subprocess.PIPE)
grep = subprocess.Popen(['grep', 'py'], stdin=ls.stdout, stdout=subprocess.PIPE)
ls.stdout.close()
output = grep.communicate()[0]
print(output.decode())

stdin=ls.stdout将ls的输出连接到grep的输入。ls.stdout.close()在父进程中关闭管道副本,避免死锁。

超时控制:

try:
result = subprocess.run(
['sleep', '10'],
timeout=5,
capture_output=True
)
except subprocess.TimeoutExpired:
print("Process timed out")

timeout=5设置超时。超时后杀死子进程并抛出TimeoutExpired。

环境变量控制:

import os

env = os.environ.copy()
env['MY_VAR'] = 'custom_value'

result = subprocess.run(
['printenv', 'MY_VAR'],
env=env,
capture_output=True,
text=True
)
print(result.stdout) # custom_value

env=dict提供子进程的完整环境变量。省略env继承当前进程的环境。

工作目录:

result = subprocess.run(
['pwd'],
cwd='/tmp',
capture_output=True,
text=True
)
print(result.stdout.strip()) # /tmp

cwd='/tmp'设置子进程的工作目录。

输入重定向:

result = subprocess.run(
['sort'],
input='banana\napple\ncherry\n',
capture_output=True,
text=True
)
print(result.stdout) # apple banana cherry (排序后)

input='string'将字符串作为子进程的stdin。

错误处理:

result = subprocess.run(
['false'],
capture_output=True
)
if result.returncode != 0:
print(f"Process failed with code {result.returncode}")

通过returncode检查进程退出状态。check=True时异常会在非零返回时抛出CalledProcessError。

shell注入防护:

# 正确:参数列表方式(无注入风险)
subprocess.run(['ls', '-la', user_input])

# 错误:字符串方式(有注入风险)
# subprocess.run(f'ls -la {user_input}', shell=True) # 危险

参数列表方式自动转义参数,shell=True时需手动处理user_input。

Popen的其他参数:

proc = subprocess.Popen(
['long_running_process'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
bufsize=0, # 无缓冲
universal_newlines=True, # 文本模式(Python 3.7+用text=True)
start_new_session=True, # 创建新进程组
creationflags=0 # Windows特定标志
)

start_new_session=True创建新的进程组,子进程及其子孙进程可以一起管理。

进程组管理:

import signal

proc = subprocess.Popen(
['long_running_script.sh'],
start_new_session=True,
)

# 杀死整个进程组
import os
pgid = os.getpgid(proc.pid)
os.killpg(pgid, signal.SIGTERM)

进程组确保子进程创建的孙进程也被终止。

异步Popen:

import asyncio

async def run_command(cmd):
proc = await asyncio.create_subprocess_shell(
cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await proc.communicate()
return stdout, stderr, proc.returncode

asyncio.create_subprocess_exec使用exec方式(推荐),create_subprocess_shell使用shell方式。

资源限制:

import resource

def set_limits():
resource.setrlimit(resource.RLIMIT_CPU, (1, 1))
resource.setrlimit(resource.RLIMIT_AS, (100 * 1024 * 1024, 100 * 1024 * 1024))

proc = subprocess.Popen(
['some_command'],
preexec_fn=set_limits # Linux
)

preexec_fn在子进程中fork后exec前执行。可以设置资源限制(RLIMIT_CPU, RLIMIT_AS等)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/16 3:50:52

2026年八大AI论文工具使用心得:用对AI论文工具=保住学位

说句实在话,刚看到那条新闻的时候,我整个人是发懵的。 前几天刷手机,刷到教育部又出了新规——高校毕业论文抽查力度要加大,而且不是以前那种象征性的抽几本翻翻,是动真格的。我有个学长就栽在这上面了,论…

作者头像 李华
网站建设 2026/6/16 3:46:50

3个核心技术:解决STL到STEP格式转换的完整指南

3个核心技术:解决STL到STEP格式转换的完整指南 【免费下载链接】stltostp Convert stl files to STEP brep files 项目地址: https://gitcode.com/gh_mirrors/st/stltostp 你是否曾面临3D打印模型无法在CAD软件中编辑的困境?当3D扫描获得的STL文件…

作者头像 李华
网站建设 2026/6/16 3:42:51

3步实现Windows电脑接收AirPlay投屏:完全免费开源方案指南

3步实现Windows电脑接收AirPlay投屏:完全免费开源方案指南 【免费下载链接】airplay2-win Airplay2 for windows 项目地址: https://gitcode.com/gh_mirrors/ai/airplay2-win AirPlay2-Win是一款专为Windows系统设计的开源AirPlay接收器解决方案,…

作者头像 李华
网站建设 2026/6/16 3:39:58

线性代数在机器学习中的三大核心应用:方程组、逆矩阵与线性相关性

1. 线性代数:机器学习里那个从不抢镜却撑起全场的“幕后工程师”你有没有拆开过一台笔记本电脑?主板上密密麻麻的芯片、电容、走线,真正让屏幕亮起来、让键盘响应、让程序跑起来的,从来不是最显眼的CPU或显卡,而是那些…

作者头像 李华
网站建设 2026/6/16 3:39:50

5分钟快速上手:通达信缠论插件ChanlunX实现自动中枢绘制与笔段分析

5分钟快速上手:通达信缠论插件ChanlunX实现自动中枢绘制与笔段分析 【免费下载链接】ChanlunX 缠中说禅炒股缠论可视化插件 项目地址: https://gitcode.com/gh_mirrors/ch/ChanlunX 还在为缠论分析中的复杂笔段划分和中枢识别而苦恼吗?ChanlunX缠…

作者头像 李华
网站建设 2026/6/16 3:31:50

复杂模型机构建实战:从架构设计到电商销量预测系统落地

1. 项目概述:从“复杂”到“清晰”的模型构建之路“复杂模型机”这个名字,听起来像是一个充满神秘感的黑箱,或者是一个堆砌了无数晦涩公式的庞然大物。但在我十多年的项目实践中,我逐渐意识到,真正有价值的“复杂模型”…

作者头像 李华