我使用 Git 来部署我的 Web 应用程序。所以在 Teamcity 中,我准备了我的应用程序(编译、缩小 JS 和 HTML、删除未使用的文件等...),然后我有一个 Powershell 构建步骤:
$ErrorActionPreference = "Stop"
git init
git remote add origin '%env.gitFolder%'
git fetch
git reset --mixed origin/master
git add .
git commit -m '%build.number%'
git push origin master
但是如果抛出异常,脚本会继续(即使我设置了
$ErrorActionPreference = "Stop"
)并且构建成功。我希望脚本在出现错误时停止,并且构建失败。
我试着把
Format stderr output as: error
在构建步骤和 Fail build if: an error message is logged by build runner
,所以构建失败,但脚本继续,所以它创建了一个愚蠢的提交。我尝试在我的脚本中放入一个 try-catch,但它没有进入 catch ......
有没有人有停止脚本的想法并因错误而导致构建失败?
对不起我的英语,我是法国人...^^
最佳答案
$ErrorActionPreference
变量不适用于调用外部实用程序 ([控制台] 应用程序)如 git
.
只有确定外部实用程序成功与失败的两种方法 :
$LASTEXITCODE
变量 ,PowerShell 将其设置为 **外部实用程序报告的退出代码**。按照惯例,值为
0
表示成功 , 而任何 非零值表示失败 . (请注意,某些实用程序,例如 robocopy.exe
,也使用某些非零退出代码来传达非错误条件。)$?
,反射(reflect)了 $True
退出代码 0
, 和 $False
对于任何非零退出代码。PSNotApplyErrorActionToStderr
暂时修复的7.2 预览版中的实验性功能 (!)(默认情况下,所有实验性功能在新安装的预览版中都处于打开状态)——我们希望这些修复能够进入 7.2:$?
可以虚假反射(reflect)$false
当$LASTEXITCODE
是 0
并且使用 stderr 重定向( 2>
或 *>
)并且命令发出 stderr 输出(这本身并不一定表示失败) - 参见 GitHub issue #10512 .$LASTEXITCODE
是一个好习惯。 ,不是 $?
推断失败与成功。 $ErrorActionPreference
设置为 'Stop'
而你碰巧使用了 2>
或 *>
使用外部程序,该程序产生实际的 stderr 输出,$ErrorActionPreference
意外地适用并导致脚本终止错误(无论外部程序是否通过非零退出代码表示实际失败) - 参见 GitHub issue #4002对故障采取行动需要明确的行动 ,通常使用
Throw
关键字以生成脚本终止错误。但是,请注意有一个 pending RFC这建议将外部程序调用正确集成到 PowerShell future 版本的错误处理机制中。
显然,检查
$LASTEXITCODE
/$?
在每次外部实用程序调用之后都很麻烦,所以这里有一个 包装函数 促进这一过程:备注 :虽然此功能有效,但它不会尝试补偿 broken-up-to-at-least-v7.1 passing of arguments with embedded double quotes to external programs .要获得此补偿,您可以使用
iee
来自 Native module 的函数 ,可通过 Install-Module Native
从 PowerShell 库安装.function Invoke-Utility {
<#
.SYNOPSIS
Invokes an external utility, ensuring successful execution.
.DESCRIPTION
Invokes an external utility (program) and, if the utility indicates failure by
way of a nonzero exit code, throws a script-terminating error.
* Pass the command the way you would execute the command directly.
* Do NOT use & as the first argument if the executable name is not a literal.
.EXAMPLE
Invoke-Utility git push
Executes `git push` and throws a script-terminating error if the exit code
is nonzero.
#>
$exe, $argsForExe = $Args
# Workaround: Prevents 2> redirections applied to calls to this function
# from accidentally triggering a terminating error.
# See bug report at https://github.com/PowerShell/PowerShell/issues/4002
$ErrorActionPreference = 'Continue'
try { & $exe $argsForExe } catch { Throw } # catch is triggered ONLY if $exe can't be found, never for errors reported by $exe itself
if ($LASTEXITCODE) { Throw "$exe indicated failure (exit code $LASTEXITCODE; full command: $Args)." }
}
现在你只需要添加 Invoke-Utility
给你所有的 git
调用,如果其中任何一个报告非零退出代码,则脚本将中止。如果这太冗长,请为您的函数定义一个别名:
Set-Alias iu Invoke-Utility
,在这种情况下,您只需要添加 iu
:iu git init
iu git remote add origin '%env.gitFolder%'
iu git fetch
# ...
关于git - 带有 Git 命令错误处理的 Powershell - 自动中止外部程序的非零退出代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48864988/