我希望我的PowerShell脚本在我运行的任何命令失败时停止(如bash中的set -e)。我正在使用Powershell命令(New-Object System.Net.WebClient)和程序(.\setup.exe)。
当前回答
对@alastairtree的回答做了一点修改:
function Invoke-Call {
param (
[scriptblock]$ScriptBlock,
[string]$ErrorAction = $ErrorActionPreference
)
& @ScriptBlock
if (($lastexitcode -ne 0) -and $ErrorAction -eq "Stop") {
exit $lastexitcode
}
}
Invoke-Call -ScriptBlock { dotnet build . } -ErrorAction Stop
这里的关键区别是:
它使用动词-名词(模仿Invoke-Command) 暗示它在幕后使用调用操作符 模仿内置cmdlet中的-ErrorAction行为 使用相同的退出代码退出,而不是使用新消息抛出异常
其他回答
对于powershell函数和调用exe函数,您需要稍微不同的错误处理,并且您需要确保告诉脚本的调用者它失败了。构建在Psake库的Exec之上,具有下面结构的脚本将在所有错误时停止,并可作为大多数脚本的基本模板。
Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"
# Taken from psake https://github.com/psake/psake
<#
.SYNOPSIS
This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
to see if an error occcured. If an error is detected then an exception is thrown.
This function allows you to run command-line programs without having to
explicitly check the $lastexitcode variable.
.EXAMPLE
exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
#>
function Exec
{
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
[Parameter(Position=1,Mandatory=0)][string]$errorMessage = ("Error executing command {0}" -f $cmd)
)
& $cmd
if ($lastexitcode -ne 0) {
throw ("Exec: " + $errorMessage)
}
}
Try {
# Put all your stuff inside here!
# powershell functions called as normal and try..catch reports errors
New-Object System.Net.WebClient
# call exe's and check their exit code using Exec
Exec { setup.exe }
} Catch {
# tell the caller it has all gone wrong
$host.SetShouldExit(-1)
throw
}
我来这里也是为了寻找同样的东西。$ErrorActionPreference="Stop"立即杀死我的shell时,我宁愿看到错误消息(暂停)之前,它终止。回到我的批处理敏感性:
IF %ERRORLEVEL% NEQ 0 pause & GOTO EOF
我发现这对我的特定ps1脚本几乎是一样的:
Import-PSSession $Session
If ($? -ne "True") {Pause; Exit}
对@alastairtree的回答做了一点修改:
function Invoke-Call {
param (
[scriptblock]$ScriptBlock,
[string]$ErrorAction = $ErrorActionPreference
)
& @ScriptBlock
if (($lastexitcode -ne 0) -and $ErrorAction -eq "Stop") {
exit $lastexitcode
}
}
Invoke-Call -ScriptBlock { dotnet build . } -ErrorAction Stop
这里的关键区别是:
它使用动词-名词(模仿Invoke-Command) 暗示它在幕后使用调用操作符 模仿内置cmdlet中的-ErrorAction行为 使用相同的退出代码退出,而不是使用新消息抛出异常
您应该能够通过在脚本的开头使用语句$ErrorActionPreference = "Stop"来实现这一点。
$ErrorActionPreference的默认设置是Continue,这就是为什么你看到你的脚本在错误发生后继续运行。
$ErrorActionPreference = "Stop"将得到你的部分方式(即这是cmdlets的伟大作品)。
然而,对于EXEs,你需要检查$LastExitCode自己后,每exe调用,并确定是否失败了。不幸的是,我不认为PowerShell可以在这里提供帮助,因为在Windows上,EXEs对于“成功”或“失败”退出码的构成并不是非常一致。大多数遵循UNIX标准,0表示成功,但并非所有都这样做。在这篇博客文章中查看CheckLastExitCode函数。你可能会发现它很有用。
推荐文章
- 如何运行一个PowerShell脚本而不显示窗口?
- PowerShell:仅为单个命令设置环境变量
- 是否有一种方法可以通过双击.ps1文件来使PowerShell脚本工作?
- 为什么这个Windows批处理文件只执行第一行,而在命令shell中执行所有三行?
- 环境变量存储在Windows注册表的哪里?
- 有一个好的Valgrind Windows的替代品吗?
- Windows和Linux上的c++编译:ifdef开关
- 如何验证批处理文件中是否存在一个文件?
- PowerShell等价于grep -f
- “Write-Host”,“Write-Output”,或“[console]::WriteLine”之间的区别是什么?
- XAMPP -端口80被PID 4的“无法打开进程”使用!12
- 为什么git在Windows下记不住我的密码
- Powershell相当于bash的&号(&),用于分叉/运行后台进程
- Git克隆/拉不断冻结在“存储密钥在缓存?”
- PowerShell脚本在机器上返回。net框架的版本?