關於PowerShell錯誤處理的一些坑


關於PowerShell錯誤處理的一些坑

測試代碼:

Write-Host '**********test ErrorActionPreference when run commands**********'
$ErrorActionPreference = 'Continue'
Write-Host '$ErrorActionPreference=''Continue'''

Get-ChildItem notexist
Write-Host 'good'
[System.IO.File]::ReadAllText('notexist')
Write-Host 'good'
1 / 0
Write-Host 'good'
Write-Error 'bad'
Write-Host 'good'

# 如果去掉下面這些注釋,腳本會在Get-ChildItem notexist處拋出異常並停止執行
# $ErrorActionPreference = 'Stop'
# Write-host '$ErrorActionPreference=''Stop'''

# Get-ChildItem notexist
# Write-Host 'good'
# [System.IO.File]::ReadAllText('notexist')
# Write-Host 'good'
# 1 / 0
# Write-Host 'good'
# Write-Error 'bad'
# Write-Host 'good'

Write-Host '**********test ErrorActionPreference when run commands with try/catch**********'
$ErrorActionPreference = 'Continue'
Write-host '$ErrorActionPreference=''Continue'''

try {
    Get-ChildItem notexist
    Write-Host 'good'
}
catch {
    Write-Host "Exception: $_"
}
try {
    [System.IO.File]::ReadAllText('notexist')
    Write-Host 'good'
}
catch {
    Write-Host "Exception: $_"
}
try {
    1 / 0
    Write-Host 'good'
}
catch {
    Write-Host "Exception: $_"
}
try {
    Write-Error 'bad'
    Write-Host 'good'
}
catch {
    Write-Host "Exception: $_"
}

$ErrorActionPreference = 'Stop'
Write-host '$ErrorActionPreference=''Stop'''
try {
    Get-ChildItem notexist
    Write-Host 'good'
}
catch {
    Write-Host "Exception: $_"
}
try {
    [System.IO.File]::ReadAllText('notexist')
    Write-Host 'good'
}
catch {
    Write-Host "Exception: $_"
}
try {
    1 / 0
    Write-Host 'good'
}
catch {
    Write-Host "Exception: $_"
}
try {
    Write-Error 'bad'
    Write-Host 'good'
}
catch {
    Write-Host "Exception: $_"
}

輸出:

**********test ErrorActionPreference when run commands**********
$ErrorActionPreference='Continue'
Get-ChildItem : 找不到路徑“C:\notexist”,因為該路徑不存在。
所在位置 C:\test.ps1:5 字符: 1
+ Get-ChildItem notexist
+ ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\notexist:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

good
使用“1”個參數調用“ReadAllText”時發生異常:“未能找到文件“C:\notexist”。”
所在位置 C:\test.ps1:7 字符: 1
+ [System.IO.File]::ReadAllText('notexist')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FileNotFoundException

good
嘗試除以零。
所在位置 C:\test.ps1:9 字符: 1
+ 1 / 0
+ ~~~~~
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

good
C:\test.ps1 : bad
所在位置 行:1 字符: 1
+ .\test.ps1
+ ~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1

good
**********test ErrorActionPreference when run commands with try/catch**********
$ErrorActionPreference='Continue'
Get-ChildItem : 找不到路徑“C:\notexist”,因為該路徑不存在。
所在位置 C:\test.ps1:32 字符: 5
+     Get-ChildItem notexist
+     ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\notexist:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

good
Exception: 使用“1”個參數調用“ReadAllText”時發生異常:“未能找到文件“C:\notexist”。”
Exception: 嘗試除以零。
C:\test.ps1 : bad
所在位置 行:1 字符: 1
+ .\test.ps1
+ ~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1

good
$ErrorActionPreference='Stop'
Exception: 找不到路徑“C:\notexist”,因為該路徑不存在。
Exception: 使用“1”個參數調用“ReadAllText”時發生異常:“未能找到文件“C:\notexist”。”
Exception: 嘗試除以零。
Exception: bad

坑:

  • $ErrorActionPreference是發生非終結性錯誤時,控制腳本執行行為的全局變量
  • 錯誤分兩種:Terminating and non-terminating errors,終結性錯誤以及非終結性錯誤。通常情況下,異常都是終結性錯誤,終結性錯誤能被catch捕捉。但是,有些命令只會往輸出流中寫錯誤信息,但是卻不拋出異常,典型的例子就是Write-Error,這個時候產生的是非終結性錯誤,非終結性錯誤不能被catch捕捉
  • $ErrorActionPreference = 'Continue'情況下,執行腳本(無異常處理機制)時,前一條命令產生了非終結性錯誤,腳本不會停止執行。有異常處理機制時,catch會捕獲終結性錯誤的異常並處理,所以緊接着拋出異常的命令后面的命令不會再繼續執行。但是catch不會捕獲非終結性錯誤,所以緊接着產生非終結性錯誤的命令后面的命令會再繼續執行。
  • $ErrorActionPreference = 'Stop'情況下,一句話,無論產生的是終結性錯誤還是非終結性錯誤,腳本會立刻停止執行,但是如果有異常處理,那么進入catch中繼續執行。
  • 大部分內置的Cmdlet都是高級函數,可以通過指定-ErrorAction來重寫全局的$ErrorActionPreference。比如,在$ErrorActionPreference = 'Continue'情況下,執行Write-Error 'message1' -ErrorAction 'Stop'; Write-Host 'message2',第二條Write-Host 'message2'不會被執行,這是由於指定了-ErrorAction 'Stop'Write-Error產生的不再是非終結性錯誤,而是終結性錯誤,會拋出異常,由於沒有異常處理機制,所以會立刻停止執行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM