2008-08-24 15 views

答えて

9

Pythonインタプリタまたはスクリプトの「親」であるCMD.exeについて言えば、それは不可能です。すべてのPOSIXのようなシステム(今はWindowsを走らせているようですが、それは私には分かりませんが、YMMV)では、各プロセスに標準入力、標準出力、標準エラーという3つのストリームがあります。 BUデフォルト(コンソールで実行している場合)、これらのコンソールに向けられているが、リダイレクトは、パイプ表記使用可能である:

python script_a.py | python script_b.py 

これはスクリプトBの標準入力ストリームにスクリプトの標準出力ストリームをネクタイこの例では、標準エラーはコンソールに送られます。 Wikipediaのstandard streamsに関する記事を参照してください。

あなたは子プロセスの話をしている場合、あなたはそのようのpythonから起動することができます(あなたが双方向通信をしたい場合は、標準入力もオプションです):

import subprocess 
# Of course you can open things other than python here :) 
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
x = process.stderr.readline() 
y = process.stdout.readline() 
process.wait() 

は、情報のためのPython subprocessモジュールを参照してください。プロセスの管理について通信の場合、process.stdinおよびprocess.stdoutパイプは標準file objectsとみなされます。上述のように

import sys 
x = sys.stderr.readline() 
y = sys.stdin.readline() 

sys.stdinをし、sys.stdoutのは、標準ファイルオブジェクトで、sysで定義された:lassevkは、あなたがこのような何かをしたい示唆したように、標準入力からの読み込みパイプで使用する場合

、モジュール。また、pipesモジュールを見てみることもできます。

私の例のようにreadline()でデータを読み取るのは、データを取得するのにはかなり単純な方法です。出力が行指向でも非確定的でもない場合は、残念なことにウィンドウでは機能しないpollingを調べたいかもしれませんが、そこにはいくつかの代替手段があると確信しています。

+1

subprocess.Popen()を使用してPythonを起動する場合、stdin/stdout/stderrでのバッファリングを無効にする "-u"フラグを渡すと便利です。子がstdinの読み込みを開始したときに、出力がパイプにリダイレクトされた場合、Pythonはstdoutをautoflushしないので、バッファリングされた出力を永久にブロックすることになります。この問題は、pdbをラップ/自動化しようとしたときに発生しました。 –

0

どのような状況でお求めですか?

コマンドラインで起動するプログラムから出力をキャプチャしようとしていますか?

somescript.py | your-capture-program-here 

を、ちょうど、標準入力から読み込み、出力を、読むために:

はそうならば、これはそれを実行する方法です。

一方、プログラム内でそのスクリプトやcmd.exeなどを実行していて、スクリプト/プログラムが終了するまで待ってすべての出力をキャプチャしたい場合は、その外部プログラムを起動するために使用するライブラリ呼び出しを見てください。ほとんどの場合、出力を読み込んで完了を待つ何らかの方法を与える方法があります。

1

あなたはsubprocessが必要です。 17.1.1のPopenを特に見て、17.1.2で通信してください。

3

実際、あなたは間違いなく缶詰があり、それは美しく、醜く、同時に狂っています!

sys.stdoutおよびsys.stderrを、出力を収集するStringIOオブジェクトで置き換えることができます。

import sys 
import StringIO 

s = StringIO.StringIO() 

sys.stdout = s 

print "hey, this isn't going to stdout at all!" 
print "where is it ?" 

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n') 
sys.stderr.write(s.getvalue()) 

あなたがこのプログラムを実行すると、あなたがそれを見ることができます:

はここevil.pyとして保存し、例を示します

  • 何も(印刷は通常に印刷している)をstdoutに行ったん
  • stderrに書き込まれる最初の文字列は 'It'で始まる文字列です
  • 次の2行はStringIOオブジェクトで収集されたものです

このようにsys.stdout/errを置き換えることは、いわゆるmonkeypatchingのアプリケーションです。これが「サポートされている」かどうかに関わらず、意見は変わるかもしれませんが、間違いなく醜いハックですが、外部のものを1〜2回包み込むときにベーコンを節約しました。

Linuxでテストされていますが、Windowsではテストされていませんが、同様に動作するはずです。それがWindows上で動作するかどうか私に教えてください!

4

私はあなたの質問の最初の部分については良い答えを指摘できると思います。

1.    それは、Python スクリプトからPythonインタプリタの出力をキャプチャすることは可能ですか?

答えは「イエス」であり、個人的に私はPEP 343 -- The "with" Statementドキュメントの例から持ち上げられ、次のように。

from contextlib import contextmanager 
import sys 

@contextmanager 
def stdout_redirected(new_stdout): 
    saved_stdout = sys.stdout 
    sys.stdout = new_stdout 
    try: 
     yield None 
    finally: 
     sys.stdout.close() 
     sys.stdout = saved_stdout 

そして、このように使用:

with stdout_redirected(open("filename.txt", "w")): 
    print "Hello world" 

それの素敵な側面は、それはむしろ、その範囲全体よりも、スクリプトの実行のほんの一部の周りに選択的に適用することができるということである、と効果にとどまります未処理の例外がコンテキスト内で発生した場合でも例外です。あなたは、その最初の使用後に追記モードでファイルを再度開くと、単一のファイルに結果を蓄積することができます

with stdout_redirected(open("filename.txt", "w")): 
    print "Hello world" 

print "screen only output again" 

with stdout_redirected(open("filename.txt", "a")): 
    print "Hello world2" 
もちろん

、上記もまた同じにsys.stderrをリダイレクトするように拡張することができたり別のファイル。関連する質問のanswerも参照してください。

関連する問題