简体   繁体   English

PowerShell中的错误处理-检查外部程序的错误输出

[英]Error Handling in PowerShell - inspect error output from external programs

I have a script that runs a batch file. 我有一个运行批处理文件的脚本。 The batch file is throwing some errors, but runs successfully. 批处理文件引发一些错误,但运行成功。 But when the batch file throws errors, the powershell script throws an error. 但是,当批处理文件引发错误时,powershell脚本将引发错误。

Included in the output is "0 failed". 输出中包括“ 0失败”。 Is there a way to check to check to see if the code contains this message, and if it does then to ignore all errors? 有没有一种方法可以检查代码中是否包含此消息,是否忽略所有错误?

Here is some psuedocode that might be able to describe what I am trying to accomplish. 这是一些伪代码,可能能够描述我要完成的工作。

$output = ./testrunner.bat 
if ($output -Like "(0 failed)") { 
    # ignore errors
} else {
    # don't ignore errors 
}

Unfortunately, it is not easy to selectively capture stderr output from an external utility (console application) in a variable . 不幸的是, 在变量中选择性地从外部实用程序(控制台应用程序)捕获stderr输出并不容易。

The most concise, though somewhat obscure approach is (PSv4+): 最简洁(虽然有些晦涩)的方法是(PSv4 +):

# First, make sure that $ErrorActionPreference is at its default,
# 'Continue'

$stdout, $stderr = (./testrunner.bat 2>&1).Where({
  $_ -isnot [System.Management.Automation.ErrorRecord]
}, 'Split')

Note: If you're content to collect the combined stdout/stderr output in a single variable, the task simplifies to: 注意:如果您愿意将组合的 stdout / stderr输出收集到单个变量中,则该任务可简化为:

$output = ./testrunner.bat 2>&1

Note that the variables in both scenarios will contain an array of objects representing the collection of the individual output lines : stdout lines become (as onw would expect) [string] array elements, whereas PS converts stderr lines to [System.Management.Automation.ErrorRecord] instances. 请注意,在这两种情况下,变量都将包含一个对象数组 ,这些对象代表各个输出的集合 :stdout行成为(如onw所期望的) [string]数组元素,而PS将stderr行转换为[System.Management.Automation.ErrorRecord]实例。

You can then inspect the $stderr (or $output ) variable for the success/failure indicator substring - note the use of enclosing wildcard characters * , because -like always matches against the entire string (unlike the regex-matching -match operator): 然后,您可以检查$stderr (或$output )变量中的成功/失败指示符子字符串 -注意使用封闭的通配符* ,因为-like总是匹配整个字符串(与regex-matching -match运算符不同):

if ($stderr -like '*(0 failed)*') {
    # ignore errors
} else {
    # don't ignore errors 
}

As for what you experienced : 至于您所经历的

when the batch file throws errors, the powershell script throws an error. 当批处理文件引发错误时,powershell脚本将引发错误。

External programs, including batch files cannot throw errors in a PowerShell sense; 外部程序(包括批处理文件)在PowerShell的意义上不能引发错误; they integrate as follows: 它们集成如下:

  • Their exit code is recorded in $LASTEXITCODE , and $? 他们的退出代码记录在$LASTEXITCODE$? is set to $True if $LASTEXITCODE is 0 , and $False otherwise. 如果$LASTEXITCODE0 ,则设置为$True ,否则$False

  • In the regular console , stderr output is passed through to the console - not colored in red - and not logged in $Error (the in-memory log of errors). 常规控制台 ,stderr输出通过控制台通过-红色着色-在没有登录$Error (在内存中的日志错误)。 In other words: stdout and stderr lines are formatted the same. 换句话说:stdout和stderr行的格式相同。

  • Unfortunately, the ISE behaves differently and does print stderr lines as if they were PowerShell errors and does log them in $Error - see this GitHub issue . 不幸的是, ISE的行为有所不同, 并且将 stderr行显示为PowerShell错误,并确实将它们记录在$Error -请参见此GitHub问题

Therefore, it sounds like you were running from the ISE . 因此,听起来好像您正在从ISE运行。
Additionally, if $ErrorActionPreference = 'Stop' is in effect when you run your code from the ISE, not only would the first stderr line present as a PowerShell error, but it would trigger termination of your entire PowerShell script. 此外,如果从ISE运行代码时$ErrorActionPreference = 'Stop'有效,则第一条stderr行不仅会作为PowerShell错误出现,还会触发整个PowerShell脚本的终止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM