1

lsコマンドラインプログラム(つまり、GDBですが、現在はGDBに変更されていますが、簡単にするために現在変更さcatれています)のすべての入力と出力をキャッチし、後で分析するためにファイルにリダイレクトしたいと思います。

仕事に近づくことはできませんでしたが、何が悪いのか理解できません。これが私の最後の試みです:

#!/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」の最初の行でした。

さらに、GDBはCLIエディションに依存しているreadlineため、透過的にキャッチするのはそれほど簡単ではないように感じます。

4

1 に答える 1

1

それで、かなりの研究の後、私はこの問題の解決策を見つけました:

読み取りと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ます。

(ただし、終了基準についてはよくわかりませんが、詳細は確認していません)

于 2012-06-05T15:31:01.967 に答える