我需要将几个进程的标准输出和错误日志收集到一个日志文件中。
因此,每个输出必须追加到此日志文件。
我想用这样的行调用所有作业:
$p=start-process myjob.bat -redirectstandardoutput $logfile -redirecterroroutput $logfile -wait
我必须在哪里提供要附加的信息?
答案 0 :(得分:70)
要附加到文件,您需要使用稍微不同的方法。您仍然可以将单个进程的标准错误和标准输出重定向到文件,但是为了将其附加到文件,您需要执行以下操作之一:
Start-Process
&
第一种方式如下:
$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-transcript
和stop-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)