はじめに
PowerShell上でStart-Process
コマンドを使って起動したアプリケーションは-RedirectStandardOutput
やRedirectStandardError
オプションを指定することで、ログをファイルに出力できます(コンソールには出力できないので注意)。
このログを同時にコンソールにも表示させたかったのですが、思いのほか苦戦したので備忘録として共有します。
できた方法
結局出力されたログファイルを、別起動したプロセスでTailするという方法を採用しました。
下記はsomethig.logに書き込みつつ同時にコンソールにもログの内容を出力するPowerShellの例です。
try {
$logJobObj = Start-Job -ScriptBlock { Get-Content -Path ".\something.log" -Wait }
$mainProcessObj = Start-Process -PassThru -FilePath process.exe -ArgumentList "-something_argument... -RedirectStandardOutput ".\something.log" RedirectStandardError ".\something.log"
// アプリケーションが終了するまで待つ
While (!$mainProcessObj.HasExited)
{
// ログをTailしているJobの出力を受け取る
Receive-Job $logJobObj
// 適当な秒数待つ
Start-Sleep -Seconds 1
}
Receive-Job $logJobObj
}
finally {
if ($logJobObj) {
Receive-Job $logJobObj
// ログをTailしているJobを終了
Stop-Job $logJobObj
Remove-Job $logJobObj
}
}
※ ログをTailするプロセスでStart-Job
を使うのは、Start-Process
で同様のことを実行しようとするとStart-Process powershell -ArgumentList "-NoExit -Command & { Get-Content... }"
みたいに書けばよさそうです。ただ今回は起動したプロセスの出力を取得したかったので、Start-Job
を使いました。
この方法は、WindowsのPowerShell上で stdout
に出力されるアプリケーションの出力を、コンソールに出力したい場合にも使えます。
※ Windows では、Windows アプリケーションにはデフォルトでstdout
ハンドルがないため、これは出力がデフォルトでコンソールに送信されない (らしい)。
余談
Bashとかであれば。。。
tee
コマンドを使って、ファイルとコンソールの両方出力は比較的簡単にできます。例えば下記のようにすれば、something_cmdのstdout
とstderr
の両方をコンソールとsomething.logに出力することができます。
something_cmd 2>&1 | tee ./something.log
somethong_cmd > >(tee ./something.log) 2>&1
System.Diagnostics.ProcessStartInfoを使う方法
ファイル出力せずにstdout
とstderr
をコンソールに出力するだけであれば、下記のように、System.Diagnostics.ProcessStartInfoを使う方法もあるようです。
powershell - Capturing standard out and error with Start-Process - Stack Overflow
PoweShellでのファイル出力方法
こちらに分かりやすくまとめてありました。
PoweShellでのファイル出力方法あれこれ #PowerShell - Qiita
コメント