13

如何使 Powershell 的行为与带有标志的 Bash 一样set -eset -o errexit制作一个 Bash 脚本“如果一个简单的命令以非零状态退出,则立即退出”。

我以为我可以通过设置来做到这一点,$ErrorActionPreference="Stop"但这似乎不起作用。假设我有一个脚本a.ps1

$ErrorActionPreference="Stop"
& cmd /c "exit 1"
echo "cmd exited `$LastExitCode=$LastExitCode and `$?=$?"

如果我运行它

.\a. ; echo "a.ps1 exited `$LastExitCode=$LastExitCode `$?=$?"

令我惊讶的是它打印

cmd exited $LastExitCode=1 and $?=False
a.ps1 exited $LastExitCode=1 $?=True

这是怎么回事?!我希望 a.ps1 在第一行之后退出,抛出错误并设置 $? 为假。

有没有解释 $ErrorActionPreference 的官方文档?我发现的只是关于咖啡的博客上的这篇文章

4

1 回答 1

12

$ErrorActionPreference按预期工作,只是本机程序的退出代码不如 PowerShell cmdlet 表现得那么好。

对于一个cmdlet错误条件很容易确定:是否发生了异常?因此,以下内容不会达到set to的Write-Host语句:$ErrorActionPreferenceStop

Write-Error blah

或者

Get-ChildItem somepathwhichsurelydoesntexisthere

对于本机程序,退出代码为零通常表示没有发生错误,但这只是一种约定,非零退出代码表示错误也是如此。你会说如果choice存在退出代码为 1 是错误的吗?

处理此问题的唯一可靠方法是在运行本机命令后检查退出代码,并在需要时自行处理。PowerShell 不会尝试猜测结果的含义,因为在这种情况下,约定不足以保证默认行为。

如果你想让你的生活更轻松,你可以使用一个函数:

function Invoke-NativeCommand {
  $command = $args[0]
  $arguments = $args[1..($args.Length)]
  & $command @arguments
  if ($LastExitCode -ne 0) {
    Write-Error "Exit code $LastExitCode while running $command $arguments"
  }
}

但总的来说,许多程序需要不同的处理,因为它们不遵守上述约定。

于 2012-07-12T11:28:32.950 回答