本文目录导读:

Python 提供了多种方式通过管道传输进程数据,主要包括以下几种:
subprocess 模块(推荐)
管道输出到变量
import subprocess
# 获取命令输出
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
print(result.stdout) # 标准输出
print(result.stderr) # 错误输出
# 或者使用 PIPE
result = subprocess.run(['grep', 'python'], input='hello\npython\nworld',
capture_output=True, text=True)
print(result.stdout) # 输出: python
管道连接多个进程
import subprocess
# 方式1:使用 PIPE 连接进程
p1 = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(['grep', 'py'], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close() # 允许 p1 接收 SIGPIPE 信号
output = p2.communicate()[0]
print(output.decode())
# 方式2:使用 subprocess.PIPE 和 subprocess.run
result1 = subprocess.run(['echo', 'hello world'], capture_output=True, text=True)
result2 = subprocess.run(['grep', 'hello'], input=result1.stdout,
capture_output=True, text=True)
print(result2.stdout)
os.popen()(较旧方式)
import os
# 读取命令输出
with os.popen('ls -l') as f:
output = f.read()
print(output)
# 写入到命令
with os.popen('grep python', 'w') as f:
f.write('hello python\n')
f.write('hello world\n')
使用 shell 管道操作符
import subprocess
# 直接在 shell 中使用管道
result = subprocess.run('ls -l | grep py | wc -l',
shell=True, capture_output=True, text=True)
print(f"Python 文件数量: {result.stdout.strip()}")
双向管道通信
import subprocess
import time
# 创建双向管道
proc = subprocess.Popen(['cat'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True)
# 发送数据
proc.stdin.write("Hello\n")
proc.stdin.write("World\n")
proc.stdin.flush()
# 接收数据
output = proc.stdout.readline()
print(f"收到: {output.strip()}")
# 关闭并等待
proc.stdin.close()
proc.wait()
实战示例:日志监控系统
import subprocess
import time
import sys
def monitor_logs():
"""监控系统日志并过滤特定关键词"""
# 模拟 tail -f 命令
tail_proc = subprocess.Popen(
['tail', '-f', '/var/log/syslog'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
bufsize=1 # 行缓冲
)
# 创建 grep 进程过滤关键词
grep_proc = subprocess.Popen(
['grep', '--line-buffered', 'ERROR\|WARNING'],
stdin=tail_proc.stdout,
stdout=subprocess.PIPE,
text=True,
bufsize=1
)
# 关闭 tail 的 stdout 副本
tail_proc.stdout.close()
try:
# 实时读取过滤后的输出
for line in iter(grep_proc.stdout.readline, ''):
if line:
print(f"[{time.strftime('%H:%M:%S')}] {line.strip()}")
except KeyboardInterrupt:
print("\n停止监控")
finally:
tail_proc.terminate()
grep_proc.terminate()
# 运行监控(需要权限)
# monitor_logs()
数据流处理示例
import subprocess
import json
def process_data_pipeline():
"""使用管道处理数据流"""
# 创建数据生成器
data = [
{"name": "Alice", "score": 95},
{"name": "Bob", "score": 82},
{"name": "Charlie", "score": 78}
]
# 转换数据为 JSON 并通过管道传给 jq 处理
json_str = '\n'.join(json.dumps(item) for item in data)
# 使用 jq 过滤数据
result = subprocess.run(
['jq', '.name, .score'],
input=json_str,
capture_output=True,
text=True
)
print(result.stdout)
# 运行示例
process_data_pipeline()
错误处理最佳实践
import subprocess
import sys
def safe_pipeline():
"""安全的管道操作"""
try:
# 创建进程管道
p1 = subprocess.Popen(
['command1'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
p2 = subprocess.Popen(
['command2'],
stdin=p1.stdout,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# 关闭管道以避免死锁
p1.stdout.close()
# 获取输出
stdout, stderr = p2.communicate()
# 检查错误
if p2.returncode != 0:
print(f"错误: {stderr.decode()}", file=sys.stderr)
return None
return stdout.decode()
except FileNotFoundError:
print("命令未找到", file=sys.stderr)
return None
except Exception as e:
print(f"管道错误: {e}", file=sys.stderr)
return None
重要提示:
- 使用
text=True获取字符串而不是字节 - 关闭不需要的管道 防止死锁
- 设置
bufsize=1实现行缓冲 - 使用
shell=True谨慎,防止注入攻击 - 使用
communicate()安全地与子进程交互
选择哪种方式取决于你的具体需求:简单场景用 subprocess.run(),复杂管道用 Popen 对象。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播