如何在运行时将Python进程的STDIN关联到另一进程的STDOUT?
在MacOS下将Root进程的STDIN关联到指定进程的STDOUT
针对MacOS权限提升导致父子进程通信中断的问题,以下是具体实现方案:
1. 获取目标进程B的STDOUT文件路径
MacOS中可通过lsof命令查询进程的文件描述符信息,从而获取进程B的STDOUT对应路径,支持按PID或命令名定位:
命令行测试方式
- 按PID查询:
lsof -p <进程B的PID> -d 1 | awk 'NR==2 {print $9}'
- 按命令名查询(若存在多个同名进程,会返回第一个匹配结果):
lsof -c "<进程B的命令名>" -d 1 | awk 'NR==2 {print $9}'
Python代码实现路径获取
在Root进程A中执行以下代码,获取进程B的STDOUT路径:
import subprocess import sys def get_target_stdout_path(pid=None, cmd_name=None): if not pid and not cmd_name: raise ValueError("必须提供目标进程的PID或命令名") # 构造lsof命令参数 cmd_args = ['lsof', '-d', '1'] if pid: cmd_args.extend(['-p', str(pid)]) else: cmd_args.extend(['-c', cmd_name]) # 执行命令并捕获输出 result = subprocess.run( cmd_args, capture_output=True, text=True, check=False ) if result.returncode != 0: raise RuntimeError(f"查询进程信息失败: {result.stderr.strip()}") # 解析lsof输出,提取STDOUT路径 output_lines = result.stdout.strip().split('\n') if len(output_lines) < 2: raise RuntimeError("未找到目标进程的STDOUT描述符") # lsof输出第9列(索引8)为文件路径 stdout_path = output_lines[1].split()[8] return stdout_path # 示例调用:替换为你的进程B命令名或PID try: target_stdout_path = get_target_stdout_path(cmd_name="spawn_root.py") except Exception as e: print(f"错误: {e}", file=sys.stderr) sys.exit(1)
2. 关联Root进程A的STDIN到目标路径
获取路径后,关闭进程A原有STDIN,重新打开目标路径作为新的STDIN:
# 关闭原有stdin文件描述符 sys.stdin.close() # 以只读模式打开目标进程的STDOUT,作为当前进程的STDIN sys.stdin = open(target_stdout_path, 'r')
注意事项
- 权限验证:确保Root进程A有权限访问目标路径。若进程B的STDOUT是终端设备(如
/dev/ttys001),Root默认拥有访问权限;若为普通文件,需确认文件权限允许Root读取。 - 进程唯一性:使用命令名查询时,若存在多个同名进程会返回第一个匹配项,建议优先使用PID精准定位目标进程。
- 动态场景:若进程B重启或STDOUT路径变更,需重新执行上述步骤更新关联。
内容的提问来源于stack exchange,提问作者Michael Altfield
相关产品推荐
相关产品推荐

