通常可以使用$ ErrorActionPreference来停止执行错误的PS脚本,如下例中使用无效的subversion命令。脚本在第一个命令后退出。
$ErrorActionPreference='Stop'
svn foo
svn foo
使用maven命令(mvn.bat)尝试相同的操作会执行这两个命令。
$ErrorActionPreference='Stop'
mvn foo
mvn foo
最初我怀疑mvn.bat没有设置错误代码而PS只是没有看到错误。但是,$?当PS在第一个错误之后退出时,如下所示正确设置:
mvn foo
if (-not $?) {exit 1}
mvn foo
所以这是我的问题:鉴于svn.exe和mvn.bat都在失败时设置了错误代码,为什么PS脚本在mvn错误后不会停止。我觉得在全局设置“$ ErrorActionPreference = Stop”比在每个命令终止错误后执行“if(-not $?){exit 1}”更方便。
答案 0 :(得分:1)
并非所有命令行程序都以相同的方式提供错误。有些人设置退出代码。有些人没有。有些使用错误流,有些则没有。我已经看到一些命令行程序实际输出所有错误,并始终输出非零返回码。
因此,没有一个真正的安全猜测可以让它成功运行,因此几乎不可能将这种行为编入PowerShell。
$ errorActionPreference实际上会在.exe写入错误流时停止脚本,但是许多.exes会将常规输出写入控制台并且永远不会填充错误流。
但它不会可靠地奏效。就此而言,也不会是美元?如果exe返回0并且没有写入错误$?将是真的。
虽然在PowerShell中处理这些单独的.exes及其错误可能会很痛苦,但它是PowerShell高度结构化输出/错误/详细/警告/调试/进度流和一致性的一个很好的例子Cmdlets中的错误行为击败了普通的.EXE工具。
希望这有助于
答案 1 :(得分:1)
$ ErrorActionPreference控制PowerShell关于命令行开关和PowerShell函数的行为 - 它对“遗留”命令的退出代码不敏感。我自己仍然在为这个设计决策寻找解决方法 - 对于这个问题,请参考这个帖子:How to stop a PowerShell script on the first error?。您可能会得出结论,这个自定义“exec”函数是最佳解决方案:http://jameskovacs.com/2010/02/25/the-exec-problem/
关于stop-on-stderr行为,我无法在PowerShell 3中重现此行为:
Invoke-Command
{
$ErrorActionPreference='Stop'
cmd /c "echo hi >&2" # Output to stderr (this does not cause termination)
.\DoesNotExist.exe # Try to run a program that doesn't exist (this throws)
echo bye # This never executes
}
更新:使用PS远程处理时,停止在stderr上的行为似乎生效。