powershell中所有錯(cuò)誤和異常處理的方法 判斷上一個(gè)程序是否運(yùn)行成功(lastexitcode try catch trap)

01.$LASTEXITCODE$?

類(lèi)似于linux的shell腳本贮缅,powershell也可以用記錄程序退出碼的方式判斷命令是否執(zhí)行成功

其中

  1. $?表示最后一個(gè)操作的執(zhí)行狀態(tài)涛漂。如果最后一個(gè)操作成功聘芜,則包含 TRUE,失敗則包含 FALSE。

  2. $LASTEXITCODE則是返回上一次執(zhí)行的退出碼,因?yàn)閘inux程序通常用退出碼0表示執(zhí)行成功复罐,所以我們判斷$LASTEXITCODE是否為0就能判斷上次程序執(zhí)行是否成功。

總的來(lái)說(shuō)$LASTEXITCODE雄家,邏輯上還要多繞一圈效诅,所以平時(shí)方便起見(jiàn)用$?就是了。

02.trap

trap關(guān)鍵詞可以指定讓程序終結(jié)的錯(cuò)誤發(fā)生時(shí)趟济,執(zhí)行一系列語(yǔ)句填帽。

  • trap的默認(rèn)行為是在執(zhí)行完statement block里的語(yǔ)句 后顯示錯(cuò)誤,然后會(huì)繼續(xù)執(zhí)行腳本或者函數(shù)
  • 在trap中使用break可以實(shí)現(xiàn)顯示錯(cuò)誤咙好,然后退出執(zhí)行
  • 如果想要不顯示錯(cuò)誤繼續(xù)執(zhí)行,可以用continue

語(yǔ)法

trap [[<error type>]] {<statement list>}

statement list就是終結(jié)錯(cuò)誤發(fā)生時(shí)褐荷,會(huì)執(zhí)行的語(yǔ)句勾效。

錯(cuò)誤類(lèi)型定義了trap的處理范圍

trap處理所有終結(jié)錯(cuò)誤

沒(méi)有類(lèi)型定義的trap會(huì)在所有錯(cuò)誤發(fā)生的時(shí)候執(zhí)行。

當(dāng)一個(gè)讓程序終結(jié)的錯(cuò)誤沒(méi)有找到其他處理的腳本或命令叛甫,就會(huì)執(zhí)行trap里面的語(yǔ)句层宫,

下面是一個(gè)例子

trap {"Error found."}
function TrapTest {
    trap {"Error found."}
    nonsenseString
}

TrapTest

會(huì)出現(xiàn)下面的錯(cuò)誤

Error found.
nonsenseString:
Line |
   3 |      nonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.

trap 中使用$_,也就是powershell自動(dòng)生成的當(dāng)前對(duì)象,就會(huì)被替換成輸出的錯(cuò)誤

function TrapTest {
    trap {"Error found: $_"}
    nonsenseString
}

TrapTest


Error found: The term 'nonsenseString' is not recognized as the name of a
cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
nonsenseString:
Line |
   3 |      nonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.

注意: trap可以在一個(gè)作用域代碼塊(scope)的任何地方定義其监,即使定義在一個(gè)代碼塊的底部萌腿,也會(huì)捕獲整個(gè)代碼塊的錯(cuò)誤

trap處理特定的錯(cuò)誤

下面是只處理沒(méi)有找到命令的錯(cuò)誤的trap,trap的使用的是.net的異常類(lèi)型

trap [System.Management.Automation.CommandNotFoundException]
    {"Command error trapped"}

下面是系統(tǒng)異常類(lèi)型抖苦,System.Management.Automation.CommandNotFoundException是繼承自System.Exception的

trap [System.Exception] {"An error trapped"}

當(dāng)多個(gè)trap同時(shí)存在的時(shí)候powershell會(huì)匹配最精確特定的trap毁菱,如下

trap {"Other terminating error trapped" }
trap [System.Management.Automation.CommandNotFoundException] {
  "Command error trapped"
}
nonsenseString

Command error trapped
nonsenseString:
Line |
   5 |  nonsenseString
     |  ~~~~~~~~~~~~~~
     | The term 'nonsenseString' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.

trap捕獲錯(cuò)誤的作用域

trap捕獲錯(cuò)誤以后米死,會(huì)執(zhí)行trap內(nèi)部的語(yǔ)句,但是錯(cuò)誤處后續(xù)的代碼還會(huì)繼續(xù)執(zhí)行

下面是在函數(shù)內(nèi)部發(fā)生了錯(cuò)誤的情況贮庞,錯(cuò)誤被內(nèi)部的trap捕獲峦筒,并且函數(shù)的返回語(yǔ)句被正常執(zhí)行

function function1 {
    trap { "An error: " }
    NonsenseString
    "function1 was completed"
}

function1

An error:
NonsenseString:
Line |
   3 |      NonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'NonsenseString' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.
function1 was completed

下面的例子trap語(yǔ)句被放到函數(shù)外面,能夠捕獲到函數(shù)內(nèi)部的錯(cuò)誤窗慎,但是函數(shù)的返回語(yǔ)句沒(méi)有被執(zhí)行

function function2 {
    NonsenseString
    "function2 was completed"
}

trap { "An error: " }

function2

An error:
NonsenseString:
Line |
   2 |      NonsenseString
     |      ~~~~~~~~~~~~~~
     | The term 'NonsenseString' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or
if a path was included, verify that the path is correct and try again.

也就是說(shuō)物喷,trap如果在函數(shù)的外部,就可以實(shí)現(xiàn)捕獲到錯(cuò)誤就停止函數(shù)運(yùn)行的功能遮斥。

注意:多個(gè)trap定義相同類(lèi)型的錯(cuò)誤條件的時(shí)候峦失,只有最高處定義的trap會(huì)被使用

Remove-Item -ErrorAction Stop ThisFileDoesNotExist
trap { "whoops 1"; continue }
trap { "whoops 2"; continue }

注意:trap語(yǔ)句的定義域取決于它編譯的位置,如果它在一個(gè)函數(shù)或者腳本中术吗,那么當(dāng)函數(shù)或腳本退出時(shí)尉辑,他們內(nèi)部的trap語(yǔ)句就會(huì)被刪除

看下面的例子,函數(shù)外的錯(cuò)誤沒(méi)有被函數(shù)內(nèi)的trap捕獲

function function1 {
    trap { "An error: " }
    
    "function1 was completed"
}
NonsenseString

function1 was completed
NonsenseString: C:\Projects\base\test\testexit.ps1:6:1
Line |
   6 |  NonsenseString
     |  ~~~~~~~~~~~~~~
     | The term 'NonsenseString' is not recognized as a name of a cmdlet, function,
     | script file, or executable program. Check the spelling of the name, or if a
     | path was included, verify that the path is correct and try again.

使用break和continue關(guān)鍵字

在trap中使用break和continue可以決定終結(jié)錯(cuò)誤發(fā)生時(shí)藐翎,繼續(xù)運(yùn)行還是停止

默認(rèn)沒(méi)有break關(guān)鍵字的情況下是會(huì)繼續(xù)運(yùn)行的材蹬,也會(huì)輸出錯(cuò)誤

function break_example {
    trap {
        "Error trapped"
        break
    }
    1/$null
    "Function completed."
}

break_example

Error trapped
ParentContainsErrorRecordException:
Line |
   6 |      1/$null
     |      ~~~~~~~
     | Attempted to divide by zero.

使用continue語(yǔ)句,powershell將從錯(cuò)誤中恢復(fù)吝镣,并且不會(huì)輸出錯(cuò)誤流

function continue_example {
    trap {
        "Error trapped"
        continue
    }
    1/$null
    "Function completed."
}

continue_example

Error trapped
Function completed.

綜上堤器,trap是一種比較簡(jiǎn)單的廣范圍的錯(cuò)誤處理方式,對(duì)于更細(xì)粒度的錯(cuò)誤處理末贾,建議使用try catch語(yǔ)句

03.try catch finally

try 捕獲的錯(cuò)誤闸溃,會(huì)被自動(dòng)保存到$Error變量里面,powershell會(huì)尋找catch語(yǔ)句來(lái)處理錯(cuò)誤拱撵。

這個(gè)語(yǔ)法就和c#的異常處理比較像

語(yǔ)法

try {<statement list>}`
catch [[<error type>][',' <error type>]*] {<statement list>}
finally {<statement list>}

捕獲錯(cuò)誤

try { NonsenseString }
catch { "An error occurred." }

An error occurred.

使用多個(gè)catch語(yǔ)句

try {
   $wc = new-object System.Net.WebClient
   $wc.DownloadFile("http://www.contoso.com/MyDoc.doc","c:\temp\MyDoc.doc")
}
catch [System.Net.WebException],[System.IO.IOException] {
    "Unable to download MyDoc.doc from http://www.contoso.com."
}
catch {
    "An error occurred that could not be resolved."
}

在try catch語(yǔ)句中使用trap

當(dāng)try語(yǔ)句中包含trap辉川,即使聲明了catch語(yǔ)句,也會(huì)執(zhí)行trap拴测,如果trap的位置比try更高乓旗,并且沒(méi)有catch語(yǔ)句,trap也會(huì)獲得控制集索,即使父級(jí)作用域中包含匹配的catch語(yǔ)句屿愚。

訪(fǎng)問(wèn)錯(cuò)誤信息 ACCESSING EXCEPTION INFORMATION

catch語(yǔ)句中的$_就包含了錯(cuò)誤信息

try { NonsenseString }
catch {
  Write-Host "An error occurred:"
  Write-Host $_
}

An Error occurred:
The term 'NonsenseString' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.

你還可以用$_打印堆棧信息

try { NonsenseString }
catch {
  Write-Host "An error occurred:"
  Write-Host $_.ScriptStackTrace
}

An Error occurred:
at <ScriptBlock>, <No file>: line 2

使用FINALLY來(lái)釋放資源

不管try塊是否遇到錯(cuò)誤,finally語(yǔ)句都會(huì)執(zhí)行务荆。即使catch中使用exit退出腳本妆距,或者使用ctrl+c中止腳本都會(huì)執(zhí)行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末函匕,一起剝皮案震驚了整個(gè)濱河市娱据,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盅惜,老刑警劉巖中剩,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忌穿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡咽安,警方通過(guò)查閱死者的電腦和手機(jī)伴网,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)妆棒,“玉大人澡腾,你說(shuō)我怎么就攤上這事「馍海” “怎么了动分?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)红选。 經(jīng)常有香客問(wèn)我澜公,道長(zhǎng),這世上最難降的妖魔是什么喇肋? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任坟乾,我火速辦了婚禮,結(jié)果婚禮上蝶防,老公的妹妹穿的比我還像新娘甚侣。我一直安慰自己,他們只是感情好间学,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布殷费。 她就那樣靜靜地躺著,像睡著了一般低葫。 火紅的嫁衣襯著肌膚如雪详羡。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 50,096評(píng)論 1 291
  • 那天嘿悬,我揣著相機(jī)與錄音实柠,去河邊找鬼。 笑死善涨,一個(gè)胖子當(dāng)著我的面吹牛主到,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播躯概,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼畔师!你這毒婦竟也來(lái)了娶靡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤看锉,失蹤者是張志新(化名)和其女友劉穎姿锭,沒(méi)想到半個(gè)月后奸汇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體票灰,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胰丁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡曲尸,死狀恐怖雀费,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情忿磅,我是刑警寧澤糯彬,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站葱她,受9級(jí)特大地震影響撩扒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吨些,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一搓谆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧豪墅,春花似錦泉手、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至状囱,卻和暖如春术裸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亭枷。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工袭艺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叨粘。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓猾编,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親升敲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子答倡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容