我希望我的PowerShell脚本在我运行的任何命令失败时停止(如bash中的set -e)。我正在使用Powershell命令(New-Object System.Net.WebClient)和程序(.\setup.exe)。
当前回答
对于2021年来到这里的人,这是我的解决方案,涵盖了cmdlet和程序
function CheckLastExitCode {
param ([int[]]$SuccessCodes = @(0))
if (!$?) {
Write-Host "Last CMD failed" -ForegroundColor Red
#GoToWrapperDirectory in my code I go back to the original directory that launched the script
exit
}
if ($SuccessCodes -notcontains $LastExitCode) {
Write-Host "EXE RETURNED EXIT CODE $LastExitCode" -ForegroundColor Red
#GoToWrapperDirectory in my code I go back to the original directory that launched the script
exit
}
}
你可以这样用
cd NonExistingpath
CheckLastExitCode
其他回答
对于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
}
我刚接触powershell,但这似乎是最有效的:
doSomething -arg myArg
if (-not $?) {throw "Failed to doSomething"}
据我所知,Powershell对它调用的子程序返回的非零退出码没有任何自动处理。
到目前为止,我所知道的模仿bash -e行为的唯一解决方案是在每次调用外部命令后添加这个检查:
if(!$?) { Exit $LASTEXITCODE }
您应该能够通过在脚本的开头使用语句$ErrorActionPreference = "Stop"来实现这一点。
$ErrorActionPreference的默认设置是Continue,这就是为什么你看到你的脚本在错误发生后继续运行。
看来简单的重掷就行了。
param ([string] $Path, [string] $Find, [string] $Replace)
try {
((Get-Content -path $Path -Raw) -replace $Find, $Replace) | Set-Content -Path $Path
Write-Output Completed.
} catch {
# Without try/catch block errors don't interrupt program flow.
throw
}
现在只有在成功执行之后才会出现输出Completed。
推荐文章
- 如何运行一个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框架的版本?