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

时间:2012-01-19 11:32:57

标签: powershell powershell-v2.0

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

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

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

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

我必须在哪里提供要附加的信息?

4 个答案:

答案 0 :(得分:70)

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

  1. 读取Start-Process
  2. 创建的stdout / stderr文件内容
  3. 不使用Start-Process并使用the call operator, &
  4. 不使用Start-Process并使用.NET对象启动该过程
  5. 第一种方式如下:

    $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
    

答案 1 :(得分: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代码附加到运行外部命令的每一行。

答案 2 :(得分:17)

与Unix shell一样,PowerShell支持>重定向,其中包含大多数来自Unix的变体,包括2>&1(虽然很奇怪,顺序无关紧要 - 2>&1 > file就像正常一样> file 2>&1)。

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

所以你的实现可能是:

& myjob.bat *>> $logfile

答案 3 :(得分:0)

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

$p = Start-Process myjob.bat -redirectstandardoutput $logtempfile -redirecterroroutput $logtempfile -wait
add-content $logfile (get-content $logtempfile)