我希望我的PowerShell脚本在我运行的任何命令失败时停止(如bash中的set -e)。我正在使用Powershell命令(New-Object System.Net.WebClient)和程序(.\setup.exe)。
当前回答
重定向stderr到stdout似乎也没有任何其他命令/scriptblock包装的技巧,尽管我找不到一个解释为什么它是这样工作的。
# test.ps1
$ErrorActionPreference = "Stop"
aws s3 ls s3://xxx
echo "==> pass"
aws s3 ls s3://xxx 2>&1
echo "shouldn't be here"
这将如预期的那样输出以下内容(命令aws s3…返回$LASTEXITCODE = 255)
PS> .\test.ps1
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
==> pass
其他回答
对于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
看来简单的重掷就行了。
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。
您应该能够通过在脚本的开头使用语句$ErrorActionPreference = "Stop"来实现这一点。
$ErrorActionPreference的默认设置是Continue,这就是为什么你看到你的脚本在错误发生后继续运行。
$ErrorActionPreference = "Stop"将得到你的部分方式(即这是cmdlets的伟大作品)。
然而,对于EXEs,你需要检查$LastExitCode自己后,每exe调用,并确定是否失败了。不幸的是,我不认为PowerShell可以在这里提供帮助,因为在Windows上,EXEs对于“成功”或“失败”退出码的构成并不是非常一致。大多数遵循UNIX标准,0表示成功,但并非所有都这样做。在这篇博客文章中查看CheckLastExitCode函数。你可能会发现它很有用。
不幸的是,由于有bug的cmdlet,如New-RegKey和Clear-Disk,这些答案都不够。我目前在一个名为ps_support.ps1的文件中确定了以下代码:
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
function ThrowOnNativeFailure {
if (-not $?)
{
throw 'Native Failure'
}
}
然后在任何powershell文件中,在文件(如果存在)的CmdletBinding和Param之后,我有以下内容:
$ErrorActionPreference = "Stop"
. "$PSScriptRoot\ps_support.ps1"
重复的ErrorActionPreference = "Stop"行是有意的。如果我犯了错误,以某种方式获得了ps_support的路径。Ps1错了,那需要的不是默默的失败!
我保留ps_support。Ps1位于我的repo/workspace的公共位置,因此点源的路径可能会根据当前. Ps1文件的位置而改变。
任何本地调用都会得到这样的处理:
native_call.exe
ThrowOnNativeFailure
在编写powershell脚本时,使用该文件进行点源可以帮助我保持头脑清醒。: -)
推荐文章
- 如何在PowerShell中获得MD5校验和
- 如何在PowerShell格式化日期时间
- PowerShell和-contains操作符
- 在Sublime Text 2中使用Ctrl+D进行多个选择时,我如何跳过匹配?
- #定义WIN32_LEAN_AND_MEAN具体排除了什么?
- 使用PowerShell删除超过15天的文件
- 最好的轻量级web服务器(只有静态内容)的Windows
- npm犯错!错误:EPERM:操作不允许,重命名
- 崇高的文本从命令行
- 如何保持Python脚本输出窗口打开?
- 使用.bat文件检查文件夹是否存在
- 如何查看Windows库(*.lib)的内容
- 在Windows中删除大文件夹最快的方法是什么?
- NPM卡住给出相同的错误EISDIR:对目录的非法操作,读取错误(本机)
- Windows 10环境变量太大