在一次运行中,是否可以将外部程序的stdoutredirect到外部程序的variables和stderr?
例如:
$global:ERRORS = @(); $global:PROGERR = @(); function test(){ # Can we redirect errors to $PROGERR here, leaving stdout for $OUTPUT? $OUTPUT = (& myprogram.exe 'argv[0]', 'argv[1]'); if ( $OUTPUT | select-string -Pattern "foo" ) { # do stuff } else { $global:ERRORS += "test(): oh noes! 'foo' missing!"; } } test; if ( @($global:ERRORS).length -gt 0 ) { Write-Host "Script specific error occurred"; foreach ( $err in $global:ERRORS ) { $host.ui.WriteErrorLine("err: $err"); } } else { Write-Host "Script ran fine!"; } if ( @($global:PROGERR).length -gt 0 ) { # do stuff } else { Write-Host "External program ran fine!"; }
一个沉闷的例子,但我想知道如果这是可能的?
最简单的方法是使用stderr输出的文件,例如:
$output = & myprogram.exe 'argv[0]', 'argv[1]' 2>stderr.txt $err = get-content stderr.txt if ($LastExitCode -ne 0) { ... handle error ... }
我也会使用$ LastExitCode检查来自本地控制台exes的错误。
一种选择是将stdout和stderr的输出合并为一个流,然后进行过滤。
stdout的数据将是字符串,而stderr会生成System.Management.Automation.ErrorRecord对象。
$allOutput = & myprogram.exe 2>&1 $stderr = $allOutput | ?{ $_ -is [System.Management.Automation.ErrorRecord] } $stdout = $allOutput | ?{ $_ -isnot [System.Management.Automation.ErrorRecord] }
您应该使用启动进程和-RedirectStandardError -RedirectStandardOutput选项。 这个其他职位有一个很好的例子,如何做到这一点(从下面的帖子中抽样):
$pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = "ping.exe" $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true $pinfo.UseShellExecute = $false $pinfo.Arguments = "localhost" $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $p.Start() | Out-Null $p.WaitForExit() $stdout = $p.StandardOutput.ReadToEnd() $stderr = $p.StandardError.ReadToEnd() Write-Host "stdout: $stdout" Write-Host "stderr: $stderr" Write-Host "exit code: " + $p.ExitCode
这也是我用来重定向命令行的stdout和stderr,同时在powershell执行期间仍然显示输出的替代方案:
$command = "myexecutable.exe my command line params" Invoke-Expression $command -OutVariable output -ErrorVariable errors Write-Host "STDOUT" Write-Host $output Write-Host "STDERR" Write-Host $errors
只是补充已经给出的另一种可能性。
请记住,这可能并不总是工作取决于如何调用脚本,我从标准的命令行而不是像这样的PowerShell命令行调用时有-OutVariable和-ErrorVariable的问题:
PowerShell -File ".\FileName.ps1"
似乎在大多数情况下工作的替代方案是这样的:
$stdOutAndError = Invoke-Expression "$command 2>&1"
不幸的是,在执行脚本的过程中,你将失去输出到命令行,并且在命令返回之后,必须Write-Host $stdOutAndError
,使其成为“记录的一部分”(如Jenkins批处理文件运行的一部分)。 不幸的是,它不分隔stdout和stderr。