我需要将多个进程的标准输出和错误日志收集到一个单独的日志文件中。
因此,每个输出必须追加到该日志文件中。
我希望使用类似于以下行的方式调用所有作业:
$p=start-process myjob.bat -redirectstandardoutput $logfile -redirecterroroutput $logfile -wait
我应该把要添加的信息放在哪里?
我需要将多个进程的标准输出和错误日志收集到一个单独的日志文件中。
因此,每个输出必须追加到该日志文件中。
我希望使用类似于以下行的方式调用所有作业:
$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
& 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
与Unix shell类似,PowerShell支持使用>
重定向输出流,并支持Unix中的大多数变种,包括2>&1
。尽管有点奇怪,顺序不重要 - 2>&1 > file
的效果与正常的> file 2>&1
相同。
与现代Unix shell大多数情况一样,PowerShell还具有将标准错误和标准输出重定向到同一设备的快捷方式,虽然与其他遵循Unix惯例的缩写不同,此缩写使用了一个新的符号,书写方式如下:*>
。
因此,您的实现可能是:
& myjob.bat *>> $logfile
Andy给了我一些好的指导,但我想用更清晰的方式来做。更不用说使用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的标准输出,然后交给记录器去处理。
实际上,我不知道为什么微软的工程师说他们还没有修复这个问题,原因是“成本高且涉及技术复杂性”,当事实上可以用如此简单的方法绕过它。
无论哪种方式,对于我来说,每次都使用 start-process
运行每个命令都会产生很多混乱,但是通过这种方法,您只需要将 2>&1 | Write-Output
代码附加到运行外部命令的每一行即可。
也许这种方法不太优雅,但以下代码也可以工作。我怀疑在异步情况下这不是一个好的解决方案。
$p = Start-Process myjob.bat -redirectstandardoutput $logtempfile -redirecterroroutput $logtempfile -wait
add-content $logfile (get-content $logtempfile)
2>&1 | Out-File $file -Append -Encoding UTF8
是唯一同时重定向标准输出和标准错误输出并使用UTF-8输出的方法。 - marsze