麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 開發(fā) > PowerShell > 正文

淺談PowerShell 捕獲錯誤

2020-03-26 19:08:00
字體:
供稿:網(wǎng)友

之前的文章我們演示了如何使用 Windows PowerShell 構(gòu)建相當(dāng)高級的清單工具。我創(chuàng)建的工具提供了多個有關(guān)輸出的選項,這應(yīng)歸功于外殼的內(nèi)置功能和將函數(shù)應(yīng)用于對象。

我所創(chuàng)建的函數(shù)有一個無可否認的弱點:它不能適度處理可能發(fā)生的任何錯誤(例如連接或權(quán)限問題)。這正是我要在本期的 Windows PowerShell 專欄中加以解決的,我將介紹 Windows PowerShell 所提供的錯誤處理功能。

設(shè)置 Trap

在 Windows PowerShell 中,Trap 關(guān)鍵字定義一個錯誤處理程序。當(dāng)您的腳本中出現(xiàn)異常時,外殼會檢查是否已經(jīng)定義 Trap,這意味著它必須在發(fā)生任何異常之前出現(xiàn)在腳本中。對于本演示,我將整理出一個會產(chǎn)生連接性問題的測試腳本:我將使用 Get-WmiObject 連接網(wǎng)絡(luò)中并不存在的計算機名。我的目標(biāo)是讓錯誤 Trap 將無效計算機名寫出到一個文件中,從而為我提供一個記錄了無效計算機名的文件。我還將加入到兩個有效計算機的連接(我將使用 localhost)。請參見圖 1 中的腳本。

添加 Trap

trap { write-host "Error connecting to $computer" -fore red "$computer" | out-file c:/demo/errors.txt -append  continue}$computer = "localhost"get-wmiobject win32_operatingsystem -comp $computer $computer = "server2"get-wmiobject win32_operatingsystem -comp $computer $computer = "localhost"get-wmiobject win32_operatingsystem -comp $computer

此腳本的輸出(如圖 2 所示)與我的期望不符。請注意 "Error connecting to…" 消息不顯示。也沒有創(chuàng)建 Errors.txt 文件。也就是說,根本沒有執(zhí)行我的 Trap。究竟發(fā)生了什么?

PowerShell,捕獲錯誤

圖 2 這不是我所希望的輸出!

停止!

關(guān)鍵在于了解正常外殼錯誤消息與異常不同(分為非終止錯誤和終止錯誤。終止錯誤會停止管道的執(zhí)行并產(chǎn)生異常)。只有異常才能被捕獲。出現(xiàn)錯誤時,外殼會檢查其內(nèi)置的 $ErrorActionPreference 變量以確定自己要執(zhí)行的操作。該變量默認含有 "Continue" 值,它表示“顯示錯誤消息并繼續(xù)”。將此變量更改為 "Stop" 會使其顯示錯誤消息并產(chǎn)生可捕獲的異常。但這意味著您腳本中的任何錯誤也將執(zhí)行該操作。

更好的方法是只讓您認為可能會引發(fā)問題的 cmdlet 使用“停止”行為??梢允褂?–ErrorAction(或 –EA)參數(shù)(一個所有 cmdlet 都支持的常見參數(shù))完成此操作。圖 3 顯示了此腳本的修訂版本。它將按照預(yù)期方式工作,產(chǎn)生的輸出如圖 4 所示。

 使用 -ErrorAction

trap { write-host "Error connecting to $computer" -fore red  "$computer" | out-file c:/demo/errors.txt -append  continue}$computer = "localhost"get-wmiobject win32_operatingsystem -comp $computer -ea stop$computer = "server2"get-wmiobject win32_operatingsystem -comp $computer -ea stop$computer = "localhost"get-wmiobject win32_operatingsystem -comp $computer -ea stop

PowerShell,捕獲錯誤

圖 4 使用 –ErrorAction 參數(shù)時我獲得了更多有用的結(jié)果

在 Trap 末尾使用 Continue 指示外殼繼續(xù)執(zhí)行產(chǎn)生異常的代碼行之后的一行。還可以使用關(guān)鍵字 Break(我將在稍后加以討論)。另請注意,$computer 變量(在腳本中定義)在 Trap 內(nèi)仍然有效。這是因為 Trap 是腳本本身的子作用域,即 Trap 可以查看腳本內(nèi)的所有變量(稍后我也將介紹此方面的更多相關(guān)信息)。

在作用域中完成所有操作

Windows PowerShell 中錯誤捕獲的一個尤為棘手的方面是作用域的使用。外殼本身代表全局作用域,它包含外殼內(nèi)部發(fā)生的所有事件。如果您運行某個腳本,它會獲取自己的腳本作用域。如果您定義某個函數(shù),該函數(shù)的內(nèi)部便是其自己的專用作用域等等。這將創(chuàng)建一種父/子類型的層次結(jié)構(gòu)。

發(fā)生異常時,外殼會在當(dāng)前作用域內(nèi)查找 Trap。這意味著某個函數(shù)內(nèi)的異常將在該函數(shù)內(nèi)部查找 Trap。如果外殼發(fā)現(xiàn)了 Trap,就會執(zhí)行該 Trap。如果 Trap 以 Continue 結(jié)尾,外殼將繼續(xù)執(zhí)行引發(fā)異常的代碼行后面的一行,但仍在同一作用域中。下面借助一小部分偽代碼來說明這一點:

Trap { # Log error to a file Continue}Get-WmiObject Win32_Service –comp "Server2" –ea "Stop"Get-Process

如果異常發(fā)生在第 5 行,則將執(zhí)行第 1 行中的 Trap。Trap 以 Continue 結(jié)尾,因此將繼續(xù)執(zhí)行第 6 行。

現(xiàn)在考慮下面這個略有些不同的作用域示例:

 Trap {  # Log error to a file  Continue }  Function MyFunction {  Get-WmiObject Win32_Service –comp "Server2" –ea "Stop"  Get-Process }  MyFunction Write-Host "Testing!"

如果錯誤發(fā)生在第 7 行,則外殼會在函數(shù)的作用域內(nèi)查找 Trap。如果沒有找到,那么外殼將退出函數(shù)的作用域,繼續(xù)在父作用域內(nèi)查找 Trap。因為那里有 Trap,所以它將執(zhí)行第 1 行。在本例中,代碼是 Continue,所以將繼續(xù)執(zhí)行同一作用域中異常之后的代碼行,即第 12 行,而不是第 8 行。換言之,外殼在退出之后不會再重新進入該函數(shù)。

現(xiàn)在將該行為與以下示例做一下對比:

Function MyFunction { Trap {  # Log error to a file  Continue } Get-WmiObject Win32_Service –comp "Server2" –ea "Stop" Get-Process} MyFunctionWrite-Host "Testing!"

在本例中,第 6 行中的錯誤將執(zhí)行第 2 行中的 Trap,并保持在函數(shù)的作用域內(nèi)。Continue 關(guān)鍵字將保持在該作用域內(nèi),繼續(xù)執(zhí)行第 7 行。如果您將 Trap 放入預(yù)期會發(fā)生錯誤的作用域內(nèi),好處是您仍保持在作用域中并可以在其中繼續(xù)執(zhí)行。但如果此方法對于您的情況不適用應(yīng)該怎么辦呢?

該工具非常適合管理配置基線。Compare-Object(或 Diff)旨在對比兩組對象。默認情況下,它將比較每個對象的所有屬性,并由該命令輸出所有不同之處。所以設(shè)想您已將某個服務(wù)器的服務(wù)完全按照您所需的方式進行了配置。只需運行下面的內(nèi)容就能創(chuàng)建基線:

Get-Service | Export-CliXML c:/baseline.xml

幾乎所有對象都可以輸送到 Export-CliXML,它會將對象轉(zhuǎn)換為 XML 文件。而后,您可以運行同一命令(如 Get-Service)并將結(jié)果與保存的 XML 進行比較。命令如下:

Compare-Object (Get-Service) (Import-CliXML  c:/baseline.xml) –property name

添加 –property 參數(shù)將強制比較僅查看該屬性,而非整個對象。在本例中,您將得到由不同于原始基線的所有服務(wù)名稱組成的列表,讓您了解在創(chuàng)建后基線是否添加或刪除了任何服務(wù)。

斷開

我在前面提到過 Break 關(guān)鍵字。圖 5 顯示了一個如何運用 Break 關(guān)鍵字的示例。

使用 Break 關(guān)鍵字

 Trap {  # Handle the error  Continue }  Function MyFunction {  Trap {   # Log error to a file   If ($condition) {    Continue   } Else {    Break   }  }  Get-WmiObject Win32_Service –comp "Server2" –ea "Stop"  Get-Process }  MyFunction Write-Host "Testing!"

以下簡要概述了執(zhí)行鏈。首先執(zhí)行第 19 行,它調(diào)用第 6 行中的函數(shù)。執(zhí)行第 15 行并產(chǎn)生異常。該異常在第 7 行捕獲,然后 Trap 必須在第 9 行做出決定。假設(shè) $condition 為 True,Trap 將在第 16 行繼續(xù)執(zhí)行。

但是,如果 $condition 為 False,Trap 將發(fā)生中斷。這將退出當(dāng)前作用域,并將原始異常傳遞至父項。從外殼角度看,這意味著第 19 行產(chǎn)生了異常,并被第 1 行捕獲。Continue 關(guān)鍵字將強制外殼繼續(xù)執(zhí)行第 20 行。

實際上,這兩個 Trap 中都包含了略多一些的代碼,用于處理錯誤,對其進行記錄等等。在本例中我只是省略了這種函數(shù)代碼,以使實際流程更易于查看。

為什么要擔(dān)心呢?

您何時需要捕獲錯誤?有兩種情況:預(yù)測可能會發(fā)生錯誤以及當(dāng)您想要某種超越普通錯誤消息的行為時(例如將錯誤記錄到文件或顯示更有幫助的錯誤消息)。

通常我在復(fù)雜一些的腳本中加入錯誤處理,以幫助處理我可以預(yù)見發(fā)生的錯誤。這些錯誤包括但不限于連接不良或權(quán)限問題等錯誤。

錯誤捕獲無疑需要花費更多的時間和精力才能了解。但當(dāng)您在 Windows PowerShell 中處理更加復(fù)雜的任務(wù)時,很有必要實施錯誤捕獲,以幫助您構(gòu)建更加完善、專業(yè)的工具。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: xxxx hd videos| 免费在线观看午夜视频 | 欧美性受ⅹ╳╳╳黑人a性爽 | 欧美一级毛片欧美一级成人毛片 | 12av毛片| 蜜桃麻豆视频 | av一道本 | 国产成人在线免费视频 | 国产日韩线路一线路二 | 99re久久最新地址获取 | 精品无吗乱吗av国产爱色 | 黄色大片大毛片 | 免费看欧美一级特黄a大片 久久免费视频一区二区三区 | 免费a级黄色片 | 黄视频网址 | 国产精品啪一品二区三区粉嫩 | 欧美精品日日鲁夜夜添 | 新久草视频 | 嫩嫩的freehdxxx | 久久精品久久久久 | 成人精品一区二区三区中文字幕 | 黄色电影免费提供 | 日本看片一区二区三区高清 | 媚药按摩痉挛w中文字幕 | 国产亚洲黑人性受xxxx精品 | 久久久青| 久久久中 | 美女在线观看视频一区二区 | 日本不卡一二三区 | 亚洲福利视频52 | 久久国产精品二区 | 亚洲视频在线观看免费视频 | 日韩视频在线观看免费视频 | 成人影片在线免费观看 | 久久久久亚洲精品 | av在线免费网址 | 美女羞羞视频网站 | 中文字幕国产日韩 | 污黄视频在线观看 | 成人在线精品视频 | 伊人午夜|