击的的PowerShell的模拟`设置-e`PowerShell

2023-09-05 23:59:30 作者:没出息的放不下.

我怎样才能让PowerShell的行为像猛砸其标志设置-e 设置-e 发出的Bash脚本退出立即如果一个简单的命令退出非零状态。

How can I make Powershell behave like Bash with its flag set -e? set -e makes a Bash script "Exit immediately if a simple command exits with a non-zero status".

我想我能做到这一点通过设置 $ ErrorAction preference =停止,但是这似乎并没有工作。假设我有一个剧本 a.ps1

I thought I could do this by setting $ErrorActionPreference="Stop" but this doesn't seem to work. Suppose I have a script 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退出第一线后,抛出一个错误,并设置$?为False。

What's going on?! I expected a.ps1 to exit after the first line, throwing an error and setting $? to False.

有任何官方文件解释$ ErrorAction preference?我所发现的是这个帖子一个关于咖啡的博客。

Is there any official documentation explaining $ErrorActionPreference? All I found was this post on a blog about coffee.

推荐答案

$ ErrorAction preference 作品为目的,它只是退出codeS从本地程序几乎没有乖巧的PowerShell命令。

$ErrorActionPreference works as intended, it's just that exit codes from native programs are not nearly as well-behaved as PowerShell cmdlets.

对于 cmdlet的错误条件是相当容易确定:是否异常发生或不?所以下面就达不到写主机语句 $ ErrorAction preference 设置为停止

For a cmdlet the error condition is fairly easy to determine: Did an exception happen or not? So the following would not reach the Write-Host statement with $ErrorActionPreference set to Stop:

Write-Error blah

Get-ChildItem somepathwhichsurelydoesntexisthere

有关本机程序为零的退出code的一般的发生没有错误,但是这仅仅是一个惯例,因为是一个非零code信号错误信号。你会说,如果的存在为1的退出code,这是一个错误?

For native programs an exit code of zero usually signals that no error occurred but that's merely a convention, as is a non-zero exit code signalling an error. Would you say that if choice exists with an exit code of 1 that it was an error?

的唯一可靠的方法来处理,这是运行本机命令和处理自己,如果需要的话后,检查出口code。 PowerShell不会试图去猜测结果的意思,因为公约是没有强大到足以保证在这种情况下,默认的行为。

The only robust way to handle this is to check the exit code after running a native command and handling it yourself, if needed. PowerShell doesn't try to guess what the result meant because the conventions aren't strong enough to warrant a default behaviour in this case.

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

You can use a function if you want to make your life easier:

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

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

But in general many programs need different handling because they don't adhere to said convention.

 
精彩推荐
图片推荐