我知道ErrorAction
的论点,还有$ErrorActionPreference
,$Error
和$
的论点。
上下文
我想解决的问题是,当运行外部命令(例如choco或git)时,它至少在我的任务上下文中会给出应警告甚至不警告的错误。
由于退出代码的存在,PowerShell认为该结果在任何意义上都是错误,例如将红色写到输出等,这在我的任务上下文中是不希望的。
我可以使用-ErrorAction
或2> $null
抑制这些命令的错误输出,但是我对使用特定命令完全消除任何错误感到沮丧。
我只想忽略那种已知的“对我来说这不是问题”类型的错误。
问题
有什么方法可以处理命令的错误,而忽略某些特定的错误,但是通常会处理所有其他错误情况?
答案 0 :(得分:3)
在常规控制台窗口 中,在PowerShell v3及更高版本中, stderr行的打印效果与标准输出行一样。
这是理想的,因为许多程序使用 stderr不仅报告真实错误,而且还报告不是数据的任何内容,例如状态消息。
Stderr行(除非重定向,请参见下文)直接在控制台上打印(而stdout行则发送到PowerShell的成功输出流中,在那里它们可以收集在变量中,通过管道发送,或通过{ {1}} / >
)。
遗憾的是,即使在v5.1 中, PowerShell ISE , 也可以在中打印stderr行红色 ,格式与PowerShell错误相同。
性能良好的控制台应用程序单独使用其退出代码表示成功(退出代码>>
)与失败(任何)非零退出代码)。 PowerShell将最近调用的控制台应用程序的退出代码保存在其自动0
变量中。
顺便说一句:
$LASTEXITCODE
和-ErrorAction
不能用于外部程序。-ErrorVariable
无效(由于<{3}},偶然除外) )。$ErrorActionPreference
/ try
不能用于检测和处理外部程序的故障。注意:我在下面的示例中使用以下外部命令,它们产生1行stdout和1行stderr输出(请注意,重定向catch
由>&2
处理,而不是PowerShell,因为它位于cmd
内部;它用于生成stderr输出):
'...'
通过非零退出代码(cmd /c 'echo stdout & echo stderr >&2'
)使命令信号失败的变体:
exit 1
因此, 通常以下内容就足够:
cmd /c 'echo stdout & echo stderr >&2 & exit 1'
这会捕获变量$stdOut = cmd /c 'echo stdout & echo stderr >&2' # std*err* will print to console
if ($LASTEXITCODE -ne 0) { Throw "cmd failed." } # handle error
中的 stdout 输出,并将 stderr 输出传递到控制台。
如果要收集以后 的stderr输出,并且仅在出现错误 时显示它们:< / p>
$stdout
请注意$stdErr = @() # initialize array for collecting stderr lines.
# Capture stdout output while collecting stderr output in $stdErr.
$stdOut = cmd /c 'echo stdout & echo stderr >&2 & exit 1' 2>&1 | Where-Object {
$fromStdErr = $_ -is [System.Management.Automation.ErrorRecord]
if ($fromStdErr) { $stdErr += $_.ToString() }
-not $fromStdErr # only output line if it came from stdout
}
# Throw an error, with the collected stderr lines included.
if ($LASTEXITCODE -ne 0) {
Throw "cmd failed with the following message(s): $stdErr"
}
重定向,它指示PowerShell通过以下方式通过管道(流2>&1
,成功流)发送stderr行(流2
,错误流)。好吧。
在1
块中,Where-Object
用于标识 stderr 行,因为PowerShell会将此类行包装在该类型的实例中。
或者,您可以将stderr输出收集到临时文件($_ -is [System.Management.Automation.ErrorRecord]
)中,读取其内容,然后将其删除。
this GitHub docs issue建议引入在变量中收集重定向的stderr输出的选项,类似于您可以如何请求 cmdlet 通过通用收集变量中的错误的方法参数
2>/path/to/tmpfile
。
有两个腔室:
从本质上讲,仅打印stderr行以后,相对于 stdout 输出的特定上下文可能会丢失。
由于This GitHub issue,-ErrorVariable
无效生效,因为$ErrorActionPreference = Stop
重定向随后会触发 script-收到第一条stderr行后,终止错误。
如果您要
注意:
从本质上讲,在处理行时,您尚不知道该程序最终将报告失败还是成功。
2>&1
注意事项也适用于此。
以下示例过滤掉stderr行$ErrorActionPreference = 'Stop'
并将行stderr1
用红色打印到控制台(仅文本,不像PowerShell错误)。
stderr2
答案 1 :(得分:-1)
我以前在git中遇到过这种情况,并通过使用$LASTEXITCODE
来解决。
不确定它是否适用于您的情况,或者因为我没有遇到问题而适用于choco。
# using git in powershell console sends everything to error stream
# this causes red text when it's not an error which is annoying
# 2>&1 redirects all to stdout, then use exit code to 'direct' output
$git_output = Invoke-Expression "& [git pull etc] 2>&1"
# handle output using exitcode
if ($LASTEXITCODE -ne 0) { throw $git_output }
else { Write-Output $git_output }