gpt4 book ai didi

python - 如何透明拦截stdin/out/err

转载 作者:太空宇宙 更新时间:2023-11-03 19:17:45 25 4
gpt4 key购买 nike

我想捕获命令行程序(即 GDB,但为了简单起见,目前更改为 lscat)的所有输入和输出,并将其重定向到一个文件,供以后分析。

我无法得到任何接近工作的东西,但我不明白出了什么问题。这是我最后一次尝试:

#!/usr/bin/env python2

import subprocess
import sys
import select
import os

def get_pipe():
fd_r, fd_w = os.pipe()
return os.fdopen(fd_r, "r"), os.fdopen(fd_w, "w")

out_r, out_w = get_pipe()
err_r, err_w = get_pipe()
in_r, in_w = get_pipe()

proc = subprocess.Popen(["ls"] + sys.argv[1:], stdin=in_r, stdout=out_w, stderr=err_w)

out_w.close()
err_w.close()
in_r.close()

running = True
while running:
input_lst, output_lst, x_lst = select.select([sys.stdin],[out_r, err_r], [], 0.5)

if out_r in output_lst+input_lst:
data = out_r.readlines()
print "*",data,"*"
if err_r in output_lst+input_lst:
data = err_r.readlines()
print "+",data,"+"
if sys.stdin in input_lst:
data = sys.stdin.readline()
print "-", data, "-"
in_w.write(data)

# don't try to quit if we received some data
if len(input_lst+output_lst+x_lst) != 0:
continue
retcode = proc.poll()
if retcode is not None:
running = False

out_r.close()
err_r.close()
in_w.close
exit(retcode)

我尝试了其他几个选项,例如 - 编写一个文件包装器,它应该将写入 stdin 的所有内容写入外部文件/从 stdout-err 读取 - 命名管道 - ...

但我得到的最好的结果是“ls”的第一行。

而且,CLI 版本的 GDB 依赖于 readline,我感觉透明地捕获它不会那么容易!

最佳答案

经过一段时间的研究,我找到了解决这个问题的方法:

non blocking读取和写入,我们只需要等待输入文件用完数据(并抛出异常),然后对输出(stdout 和 stderr)进行相同的操作:

#!/usr/bin/python2

import sys, os
import subprocess
import fcntl

dump = open("/tmp/dump", "w")
dump.write("### starting %s ###" % " ".join(sys.argv))

proc = subprocess.Popen(["<real app>"] + sys.argv[1:], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

def nonblocking(fd):
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

nonblocking(proc.stdin)
nonblocking(proc.stdout)
nonblocking(proc.stderr)

nonblocking(sys.__stdin__)
nonblocking(sys.__stdout__)
nonblocking(sys.__stderr__)

def me_to_proc():
x_to_y(sys.__stdin__, proc.stdin, "~in> ")

def proc_to_me():
x_to_y(proc.stdout, sys.__stdout__, "<out~ ")

def proc_to_me_err():
x_to_y(proc.stderr, sys.__stderr__, "<err~ ")

def x_to_y(x, y, prefix=""):
try:
while True:
line = x.readline()
to_dump = "%s%s" % (prefix, line)
print >> dump, to_dump
print to_dump
y.write(line)
y.flush()
dump.flush()
except:
pass

recode = None
while recode is None:
proc_to_me()
#proc_to_me_err()
me_to_proc()

retcode = proc.poll()

exit(retcode)

只需用此脚本替换原始二进制文件,然后更改 <real app>创建实际的流程。输入和输出信息将写入屏幕上并转储到 /tmp/dump .

(但是我不确定终止标准,我没有详细检查)

关于python - 如何透明拦截stdin/out/err,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10794894/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com