none
Start-ProcessのRedirectStandardOutputでprocessのコンソール出力結果が終了時にしか得られない RRS feed

  • 質問

  • いつも助けていただきありがとうございます。

    ■困っていること

    Start-ProcessのRedirectStandardOutputでprocessのコンソール出力結果が終了時にしか得られない

    ■したいこと
    Start-Processで呼び出しているのはpythonでpythonは標準出力(コンソール?)にログを出力※しています。
    pythonのログをリアルタイムに見たいのに、実際にはpythonが終了したときにしか出力結果を閲覧できません・・・。

    pythonの例(import os , datetimeしています)

    sys.stdout.write(u"\n{} - ■開始[{}]".format(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'),os.path.abspath(__file__)))
    ログはリアルタイムで閲覧する予定でした。例えばこんな感じで。。。
    Get-Content test.log -Wait -Tail 1000
    ■実際のコマンド
    $proc = Start-Process –FilePath "C:\Program Files\Python38\python.exe" -ArgumentList "$forExecPyScript  $forPythonPalamater" -PassThru –RedirectStandardOutput $consoleLogFile –RedirectStandardError $errorLogFile -wait
    ■質問内容
    pythonがsys.stdout.writeで標準出力(コンソール?)にログを出力するたびにRedirectStandardOutputで指定したファイルに(リアルタイムに)出力するようにするにはどのようにすればよいでしょうか。

    少し急いでいます。どうぞ、とても、よろしくお願いいたします。



    2020年2月16日 14:02

回答

  • pythonでは通常、改行を出力するたびにバッファが自動でフラッシュされますが、標準出力がリダイレクトされている場合は自動フラッシュが行われなくなるようです。

    pythonスクリプトに手を入れられるなら、sys.stdout.flush()を呼び出して明示的にフラッシュすればいいでしょう。

    <追記>毎回flushを入れるのは面倒だろうと少し調べたところ、

    • 起動引数に-uを与える(-ArgumentList @("-u", $forExecPyScript, ...) )
    • 環境変数PYTHONUNBUFFEREDをTRUEに設定する(PowerShell上では$env:PYTHONUNBUFFERED = "TRUE")

    といった方法があるようです。</追記>


    2020年2月16日 15:00

すべての返信

  • pythonでは通常、改行を出力するたびにバッファが自動でフラッシュされますが、標準出力がリダイレクトされている場合は自動フラッシュが行われなくなるようです。

    pythonスクリプトに手を入れられるなら、sys.stdout.flush()を呼び出して明示的にフラッシュすればいいでしょう。

    <追記>毎回flushを入れるのは面倒だろうと少し調べたところ、

    • 起動引数に-uを与える(-ArgumentList @("-u", $forExecPyScript, ...) )
    • 環境変数PYTHONUNBUFFEREDをTRUEに設定する(PowerShell上では$env:PYTHONUNBUFFERED = "TRUE")

    といった方法があるようです。</追記>


    2020年2月16日 15:00
  •  Hongliang様

    素早くご回答いただきましてありがとうございました。また、返信が遅くなりまして申し訳ございませんでした。

    ご回答いただいてからすぐに拝見させていただきました。

    sys.stdout.flush()で対応しようかと思っていたところ、さらに有用なご回答(PYTHONUNBUFFEREDの存在)をいただけて助かりました。

    実環境ではシステム環境変数にPYTHONUNBUFFEREDを設定し、望み通りの結果を得られました。
    ※python側の仕様による問題であるとは思ってもいませんでした。

    Hongliang様から頂きましたご回答を回答としてマークさせていただきました。

    今後ともよろしくお願いいたします。

    2020年2月21日 12:13
  • 誤解があるようなので補足します。

    Linuxのマニュアルですがstdoutの説明で

    stdout ストリームは、端末に接続されているときには行単位でバッファーリング されている。

    とあるように、端末の時とその他(リダイレクトした時)とで動作が異なるのは、標準Cライブラリとしての仕様ですので、ほぼ全てのアプリケーションに共通の動作です。その上で、その挙動をキャンセルする方法はアプリケーションごとに異なり、PythonにおいてはPYTHONUNBUFFEREDでキャンセルするように書かれている、ということです。

    2020年2月21日 14:18
  • 佐祐理様

    追加の情報をありがとうございます。より知識が深まりました。

    過去にはPOSIXサブシステム,現在はSubsystem for UNIX-based Applications (SUA)をNT系のOSに内包していることから、ご提供いただいた情報の通りになっているのかもしれませんね。

    ※上記の私の言葉の内容を裏付けるソースはありません。個人による想像で事実とは異なります。

    2020年2月24日 9:42