複数のプロセスから標準出力とエラーログを1つのログファイルに収集する必要があります。
したがって、すべての出力は、このログファイルにappendである必要があります。
次のような行ですべてのジョブを呼び出したい:
$p=start-process myjob.bat -redirectstandardoutput $logfile -redirecterroroutput $logfile -wait
追加する情報をどこに置く必要がありますか?
ファイルに追加するには、少し異なるアプローチを使用する必要があります。個々のプロセスの標準エラーと標準出力をファイルにリダイレクトすることもできますが、ファイルに追加するには、次のいずれかを実行する必要があります。
Start-Process
によって作成されたstdout/stderrファイルの内容を読む&
を使用します最初の方法は次のようになります。
$myLog = "C:\File.log"
$stdErrLog = "C:\stderr.log"
$stdOutLog = "C:\stdout.log"
Start-Process -File myjob.bat -RedirectStandardOutput $stdOutLog -RedirectStandardError $stdErrLog -wait
Get-Content $stdErrLog, $stdOutLog | Out-File $myLog -Append
2番目の方法は次のようになります。
& myjob.bat 2>&1 >> C:\MyLog.txt
またはこれ:
& myjob.bat 2>&1 | Out-File C:\MyLog.txt -Append
3番目の方法:
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "myjob.bat"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = ""
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$output = $p.StandardOutput.ReadToEnd()
$output += $p.StandardError.ReadToEnd()
$output | Out-File $myLog -Append
アンディは私に良い指針をくれましたが、もっときれいな方法でやりたかったのです。言うまでもなく、2>&1 >>
メソッドでは、PowerShellが別のプロセス、つまりstderrとstdoutの両方がアクセスのためにファイルをロックしようとすることでログファイルにアクセスすることについて不平を言いました。だからここに私がそれを回避した方法があります。
最初に、ニースのファイル名を生成しましょう。しかし、それは本当にただの教訓的です:
$name = "sync_common"
$currdate = get-date -f yyyy-MM-dd
$logfile = "c:\scripts\$name\log\$name-$currdate.txt"
そして、ここからトリックが始まります:
start-transcript -append -path $logfile
write-output "starting sync"
robocopy /mir /copyall S:\common \\10.0.0.2\common 2>&1 | Write-Output
some_other.exe /exeparams 2>&1 | Write-Output
...
write-output "ending sync"
stop-transcript
start-transcript
およびstop-transcript
を使用すると、PowerShellコマンドのすべての出力を単一のファイルにリダイレクトできますが、 外部コマンドでは正しく機能しません 。したがって、それらのすべての出力をPSのstdoutにリダイレクトし、残りはトランスクリプトに任せましょう。
実際、MSのエンジニアが、このような単純な方法で回避できるのに、「高コストと技術的な複雑さのために」これをまだ修正していないと言う理由がわかりません。
いずれにせよ、start-process
ですべてのコマンドを実行するのは非常に煩雑ですが、この方法では、外部コマンドを実行する各行に2>&1 | Write-Output
コードを追加するだけです。
Unixシェルのように、PowerShellは>
リダイレクトをサポートします。これには、2>&1
(奇妙なことに、順序は関係ありません-2>&1 > file
は通常の> file 2>&1
)。
ほとんどの最新のUnixシェルと同様に、PowerShellには標準エラーと標準出力の両方を同じデバイスにリダイレクトするためのショートカットがありますが、Unixの慣習にほぼ従う他のリダイレクトショートカットとは異なり、すべてのショートカットのキャプチャでは新しい sigil のように書かれています:*>
。
したがって、実装は次のようになります。
& myjob.bat *>> $logfile
たぶんそれはそれほどエレガントではないかもしれませんが、以下もうまくいくかもしれません。非同期的にこれは良い解決策ではないと思います。
$p = Start-Process myjob.bat -redirectstandardoutput $logtempfile -redirecterroroutput $logtempfile -wait
add-content $logfile (get-content $logtempfile)