2011-11-08 12 views
6

私はインタプリタの入力とエラーと標準出力の両方にリアルタイムでアクセスしたいと思います。できれば、この情報はファイルに書き込まれるので、すべてのインタプリタコマンドが入力された後にファイルをポーリングすることができます。私は、ログファイルに以下を見てみたいと思いますPythonの対話型シェルセッションで発生するすべてをログに記録する方法は?

>>> 5 * 7 
35 
>>> print("Hello, world!") 
Hello, world! 
>>> "Hello, world!" 
'Hello, world!' 

:たとえば、インタプリタセッションを与え

> 5 * 7 
35 
> print("Hello, world!") 
Hello, world! 
> "Hello, world!" 
'Hello, world!' 

フォーマットは重要ではありません。重要なことは、セッション中に対話的なイベントを引き起こすキーワードをファイルから検索できることです。

Pythonのcodeモジュールは私がInteractiveConsoleオブジェクト、私はそうのように、ファイルにログを記録するように再定義することができたのraw_inputメソッドを作成することができます:私はこれを達成しようと、これまでに学んだこと

def write(self, data): 
    sys.stderr.write(data) 
    self.file.write(data+'\n') 
InteractiveConsole内蔵私は再定義することができ、エラーをログに記録する writeメソッドを使用しています
import code 
class LoggedConsole(code.InteractiveConsole): 
    def __init__(self, locals): 
    super(LoggedConsole, self).__init__(locals) 
    self.file = open('consolelog.dat', 'a') 

    def __del__(self): 
    self.file.close() 

    def raw_input(self, prompt=""): 
    data = input(prompt) 
    self.file.write(data+'\n') 
    return data 
さらに

、すべて一緒に、その後LoggedConsoleオブジェクトを作成することでしたこれを持参し、地元の人々にそれをTeeを渡す

class Tee(object): 
    def __init__(self): 
    self.file = open('consolelog.dat', 'a') 
    self.stdout = sys.stdout 

    def __del__(self): 
    sys.stdout = self.stdout 
    self.file.close() 

    def write(self, data): 
    self.file.write(data) 
    self.stdout.write(data) 

sys.stdout = Tee() 

マイ(壊れた)の試行:

は、私はまた、次のコードは、すべての標準出力をログに記録することを学びました。

console = LoggedConsole(locals={sys.stdout:LoggedExec()}) 
console.interact() 

(私は前に地元の人々に合格していませんでしたので、おそらく私は間違ってここでそれをやっているが、私はエラーが表示されません。)

とにかく、これは、新しいインタラクティブコンソールを開きます。すべての入力とエラーを記録し(終了後に)記録しますが、出力は記録しません。私はしばらくこのことに頭をぶつけていました。私は近くにいるように感じますが、たぶん、そうではないかもしれません。

また、このすべてが発生する方法はありますか?セッション中ですか?セッションが終了すると、現在すべてのロギングが行われます。

あなたのお時間をありがとうございます、テキストの壁には申し訳ありません。

編集: 私は移植性のために標準のPythonインタプリタでこれを達成したいと考えています。

edit2: Jaimeのスニペットは、必要なすべてのログを記録するのに非常に有効です。しかし、セッションを閉じるのを待つのではなく、リアルタイムでそうすることができます。

edit3: それを実証しました:)。最終的に、作業スニペット:

import code 
import sys 

class Tee(object): 
    def __init__(self, log_fname, mode='a'): 
    self.log = open(log_fname, mode) 

    def __del__(self): 
    # Restore sin, so, se 
    sys.stdout = sys.__stdout__ 
    sys.stdir = sys.__stdin__ 
    sys.stderr = sys.__stderr__ 
    self.log.close() 

    def write(self, data): 
    self.log.write(data) 
    self.log.flush() 
    sys.__stdout__.write(data) 
    sys.__stdout__.flush() 

    def readline(self): 
    s = sys.__stdin__.readline() 
    sys.__stdin__.flush() 
    self.log.write(s) 
    self.log.flush() 
    return s 

    def flush(foo): 
    return 

sys.stdout = sys.stderr = sys.stdin = Tee('consolelog.dat', 'w') 

console = code.InteractiveConsole() 
console.interact() 
+0

あなたのユースケースは分かりませんが、 'ipython notebook'はインタラクティブなワークフローには大変優れています。 – Kos

答えて

7

私はpython2.7でこれをテストしてみました。私は3つ手がありません。

import code 
import sys 

class Tee(object): 

    def __init__(self, log_fname, mode='a'): 
    self.log = open(log_fname, mode) 

    def __del__(self): 
    # Restore sin, so, se 
    sys.stdout = sys.__stdout__ 
    sys.stdir = sys.__stdin__ 
    sys.stderr = sys.__stderr__ 
    self.log.close() 

    def write(self, data): 
    self.log.write(data) 
    sys.__stdout__.write(data) 

    def readline(self): 
    s = sys.__stdin__.readline() 
    self.log.write(s) 
    return s 

# Tie the ins and outs to Tee. 
sys.stdout = sys.stderr = sys.stdin = Tee('consolelog.dat', 'w') 

console = code.InteractiveConsole() 
console.interact() 
+0

これはとてもうまく動作します。どのようにしてリアルタイムでログインさせることができますか?セッションが終了するまで待機しないでください。私は 'sys.stdout.flush()'などの呼び出しがどこかで読んでいますが、実装方法については少し不明です。これまでのご協力ありがとうございました! –

+1

それを考え出した。ログファイルとstdout/inオブジェクトの両方に対して 'flush()'を呼び出す必要があります。正しい方向に私を押してくれてありがとう! –

+0

それはあなたを助けてくれてうれしいです。ログをフラッシュする必要があるだけです。 stdout/stderrをフラッシュする理由はありません。ログは実際にファイルに書き込む唯一のものなので、フラッシングすれば十分です。 – jaime

5

IPythonを見て(それを自分自身を使用していない)を取ります。ここで特に関心のあるかもしれないドキュメント内のセクションです:http://ipython.org/ipython-doc/dev/interactive/reference.html#session-logging-and-restoring

+0

ああ、私は、標準のPythonインタプリタを使用することを好むと言いました(しかし、忘れてしまいました)。私はiPythonに落ちるかもしれませんが、私は最初にこれを達成するようにしたいと思います。 –

3

iPythonセッションをログに記録する方法を示し、ダグ・ヘルマンによるthis Virtualenv articleを参照してください:

あなたは、このように対話プロンプトで快適に作業している場合セッションを閉じた後にあなたが何をするかを記録したい場合は、IPythonのログ機能を使ってファイルにセッションを書き込むことができます。ログをアクティブにするには、制御コマンド%logstartを使用します(リスト5を参照)。出力ファイルはPythonソース・ファイルなので、実験を終えたときにクリーンアップして「実際の」モジュールにするのは簡単です。

In [6]: %logstart 
Activating auto-logging. Current session state plus future input saved. 
Filename  : ipython_log.py 
Mode   : rotate 
Output logging : False 
Raw input log : False 
Timestamping : False 
State   : active 

In [7]: a = 5 

In [8]: b = 6 

In [9]: c = a * b 

In [10]: c 

Out[10]: 30 

In [11]: d = [ a, b, c] 

In [12]: d 

Out[12]: [5, 6, 30] 

In [13]: %logstop 
+0

参考になりました!しかし、私は標準的な通訳でこの作業をしたいと思います。ここでの目標は、Pythonの基礎に関するインタラクティブなチュートリアルを作成することです(そして、道に沿って自分自身を教えることです)、それを使用する可能性のある友人の利益のために移植可能にしたいと思います。 –

2

あなたは単純にしようと、UNIXスクリプトコマンドを使用することができます。

Script started on Sat Dec 14 11:18:41 2013 
python 
>> print('hi') 
hi 
>> exit() 
exit 

Script done on Sat Dec 14 11:18:59 2013 
0

script -a filename.txt 
python 
>> print("hi") 
hi 
>> exit() 
exit 

ファイル名.txtがそのセッションであなたがしたすべてを記録し、それは次のようになります

私のログツールを試してみることができます。まだ完璧ではありませんが、それは私の問題を解決しました。

https://github.com/hholst80/loginteractive

それはstdoutにパイプstdin.txt(または$ STDIN)にLD_PRELOADを使用して動作します。私はそれをテストしていませんが、それはPythonとオクターブのために動作しますそのまだ。

関連する問題