标准和错误输出的重定向附加到同一日志文件

问题描述 投票:48回答:4

我需要将几个进程的标准输出和错误日志收集到一个日志文件中。

因此,每个输出都必须附加到此日志文件。

我想用这样的行调用所有作业:

$p=start-process myjob.bat -redirectstandardoutput $logfile -redirecterroroutput $logfile -wait

我需要在哪里附加信息?

powershell powershell-v2.0
4个回答
70
投票

为了附加到文件,您需要使用稍微不同的方法。您仍然可以将单个进程的标准错误和标准输出重定向到文件,但是为了将其附加到文件,您需要执行以下操作之一:

  1. 阅读Start-Process创建的stdout / stderr文件内容
  2. 不使用Start-Process并使用the call operator, &
  3. 不使用Start-Process并使用.NET对象启动该过程

第一种方式看起来像这样:

$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

第二种方式如下:

& myjob.bat 2>&1 >> C:\MyLog.txt

或这个:

& myjob.bat 2>&1 | Out-File C:\MyLog.txt -Append

第三种方式:

$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

18
投票

安迪给了我一些好的指示,但我想以更清洁的方式做到这一点。更不用说使用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-transcriptstop-transcript,您可以将所有PowerShell命令输出重定向到单个文件,但it doesn't work correctly with external commands。所以,让我们将这些输出的所有输出重定向到PS的标准输出,然后让记录完成剩下的工作。

事实上,我不知道为什么MS工程师说它们还没有解决这个问题,“由于所涉及的高成本和技术复杂性”,它可以以这种简单的方式解决。

无论哪种方式,使用start-process运行每一个命令都是一个巨大的混乱恕我直言,但使用这种方法,你要做的就是将2>&1 | Write-Output代码附加到运行外部命令的每一行。


17
投票

与Unix shell一样,PowerShell支持>重定向,其中大部分变量都来自Unix,包括2>&1(虽然奇怪,顺序无关紧要 - 2>&1 > file的工作方式与普通的> file 2>&1一样)。

像大多数现代Unix shell一样,PowerShell也有一个快捷方式,可以将标准错误和标准输出重定向到同一个设备,不像其他重定向快捷方式几乎遵循Unix惯例,捕获所有快捷方式使用新的sigil并且写得像这样:*>

所以你的实现可能是:

& myjob.bat *>> $logfile

0
投票

也许它不是那么优雅,但以下也可能有效。我怀疑异步这不是一个好的解决方案。

$p = Start-Process myjob.bat -redirectstandardoutput $logtempfile -redirecterroroutput $logtempfile -wait
add-content $logfile (get-content $logtempfile)
© www.soinside.com 2019 - 2024. All rights reserved.