コマンドの出力をコンソールから非表示にせずにファイルに保存できるようにする Python ソリューションを探しています。
参考までに:私は、(Unix コマンド ライン ユーティリティとしての) teeについて質問していますが、Python intertools モジュールの同じ名前の関数については質問していません。
詳細
- Python ソリューション ( を呼び出し
tee
ていません。Windows では使用できません) - 呼び出されたプロセスの標準入力に入力を提供する必要はありません
- 呼び出されたプログラムを制御できません。私が知っているのは、stdout と stderr に何かを出力し、終了コードで戻るということだけです。
- 外部プログラム(サブプロセス)呼び出し時に動作させるには
- 両方のために働くため
stderr
にstdout
- stdout と stderr を区別できるのは、コンソールに 1 つだけを表示したい場合や、別の色を使用して stderr を出力しようとする場合があるためです。これは機能し
stderr = subprocess.STDOUT
ないことを意味します。 - ライブ出力 (プログレッシブ) - プロセスは長時間実行される可能性があり、終了するのを待つことができません。
- Python 3 互換コード (重要)
参考文献
これまでに見つけたいくつかの不完全なソリューションを次に示します。
- http://devlishgenius.blogspot.com/2008/10/logging-in-real-time-in-python.html (mkfifo は Unix でのみ動作します)
- http://blog.kagesenshi.org/2008/02/teeing-python-subprocesspopen-output.html (まったく動かない)
ダイアグラム http://blog.i18n.ro/wp-content/uploads/2010/06/Drawing_tee_py.png
現在のコード (2 回目の試行)
#!/usr/bin/python
from __future__ import print_function
import sys, os, time, subprocess, io, threading
cmd = "python -E test_output.py"
from threading import Thread
class StreamThread ( Thread ):
def __init__(self, buffer):
Thread.__init__(self)
self.buffer = buffer
def run ( self ):
while 1:
line = self.buffer.readline()
print(line,end="")
sys.stdout.flush()
if line == '':
break
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdoutThread = StreamThread(io.TextIOWrapper(proc.stdout))
stderrThread = StreamThread(io.TextIOWrapper(proc.stderr))
stdoutThread.start()
stderrThread.start()
proc.communicate()
stdoutThread.join()
stderrThread.join()
print("--done--")
#### test_output.py ####
#!/usr/bin/python
from __future__ import print_function
import sys, os, time
for i in range(0, 10):
if i%2:
print("stderr %s" % i, file=sys.stderr)
else:
print("stdout %s" % i, file=sys.stdout)
time.sleep(0.1)
実質出力
stderr 1
stdout 0
stderr 3
stdout 2
stderr 5
stdout 4
stderr 7
stdout 6
stderr 9
stdout 8
--done--
予想される出力は、行が順序付けられていることでした。Popen を 1 つの PIPE のみを使用するように変更することは許可されていないことに注意してください。
また、2番目のケースでもリアルタイムのようなアウトを取得できませんでしたが、実際にはプロセスが終了したときにすべての結果が受信されました. デフォルトでは、Popen はバッファーを使用しません (bufsize=0)。