当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

作者:精品下载站 日期:2024-12-14 13:00:53 浏览:14 分类:玩电脑

如何使用 PowerShell Try Catch 块提升游戏体验


您是否曾经运行过脚本或 PowerShell cmdlet,却遇到过一堵令人尖叫的红色文本墙,如下图所示?

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

错误可能会变得势不可挡且令人困惑。最重要的是,错误通常很难读取,这使得确定脚本出了什么问题以及出在哪里几乎不可能。

幸运的是,PowerShell 中有一些选项可以通过错误处理来改善这一情况。使用错误处理,可以过滤错误并以更容易理解的方式显示错误。而且,了解错误可以轻松地为错误处理添加更多逻辑。

在本文中,您将了解 PowerShell 中的错误以及如何使用 PowerShell Try Catch 块(和 finally 块)拦截这些错误以执行错误处理。

了解错误在 PowerShell 中的工作原理

在深入讨论错误处理之前,我们首先介绍一下有关 PowerShell 中错误的一些概念。了解错误可以带来更好的错误处理策略。

$Error 自动变量

在PowerShell中,有很多自动变量,其中之一就是$Error自动变量。 PowerShell 使用 $Error 变量来存储会话中遇到的所有错误。 $Error 变量是按最新排序的错误数组。

当您首次打开 PowerShell 会话时,$Error 变量为空。您可以通过调用 $Error 变量来检查它。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

正如您所看到的,$Error 变量一开始是空的。但是,一旦生成错误,该错误将被添加并存储到 $Error 变量中。

在下面的示例中,错误是由于故意获取不存在的服务名称而产生的。

PS> Get-Service xyz
PS> $Error
PS> $Error.Count

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

从上面的输出中可以看到,生成的错误已添加到 $Error 变量中。

$Error 变量包含 PowerShell 会话中生成的错误的集合。每个错误都可以通过调用其数组位置来访问。最新的错误将始终位于索引 0 处。

例如,可以使用 $Error[0] 检索最新的错误。

$Error 对象属性

由于 PowerShell 中的一切都是对象,因此 $Error 变量也是一个对象,并且对象具有属性。通过将 $Error 变量通过管道传递给 Get-Member cmdlet,您应该会看到可用属性的列表。

$Error | Get-Member

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

要确定错误的原因,您可以使用以下命令查看 InitationInfo 属性的内容。

$Error[0].InvocationInfo

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

现在,您可以对其他属性执行相同的操作,并发现您可以找到哪些其他信息!

终止错误

当 PowerShell 遇到终止错误与非终止错误时,终止错误会停止执行流。发生终止错误的方式有多种。一个示例是当您使用不存在的参数调用 cmdlet 时。

正如下面的屏幕截图所示,当命令 Get-Process notepad 运行时,该命令有效,并且会显示 notepad 进程的详细信息。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

但是,当使用不存在的参数(例如 Get-Process notepad -handle 251)时,cmdlet 会显示一条错误,指出 handle 参数无效。然后,cmdlet 退出,而不显示 notepad 进程的详细信息。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

非终止错误

非终止错误是不会停止脚本或命令执行的错误。例如,查看下面的代码。此代码从 fileslist.txt 文件中获取文件名列表。然后,脚本遍历每个文件名,读取每个文件的内容,并将其输出到屏幕上。

$file_list =  Get-Content .\filelist.txt
foreach ($file in $file_list) {
    Write-Output "Reading file $file"
    Get-Content $file
}

filelist.txt 文件的内容是下面列表中显示的文件名。

File_1.log
File_2.log
File_3.log
File_4.log
File_5.log
File_6.log
File_7.log
File_8.log
File_9.log
File_10.log

但是如果 File_6.log 实际上并不存在怎么办?当您运行代码时,您预计会发生错误,因为脚本找不到 File_6.log。您将看到如下所示的类似输出。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

从上面结果的屏幕截图中可以看到,脚本能够读取列表中的前五个文件,但是当它尝试读取文件 File_6.txt 时,会返回错误。然后该脚本在退出之前继续读取其余文件。它没有终止

$ErrorActionPreference 变量

到目前为止,您已经了解了终止错误和非终止错误以及它们之间的区别。但是,您是否知道非终止错误可以强制被视为终止错误?

PowerShell 有一个称为p引用变量的概念。这些变量用于改变 PowerShell 的多种不同行为方式。这些变量之一称为$ErrorActionPreference

$ErrorActionPreference 变量用于更改 PowerShell 处理非终止错误的方式。默认情况下,$ErrorActionPreference 值设置为Continue。将 $ErrorActionPreference 变量的值更改为 STOP 会强制 PowerShell 将所有错误视为终止错误。

使用下面的代码更改 $ErrorActionPreference 值。

$ErrorActionPreference = "STOP"

要了解有关其他有效 $ErrorActionPreference 变量值的更多信息,请访问 PowerShell ErrorActionPreference。

现在,请回顾一下本文非终止错误部分中使用的示例。可以修改脚本以包含 $ErrorActionPreference 中的更改,如下所示的代码:

# Set the $ErrorActionPreference value to STOP
$ErrorActionPreference = "STOP"
$file_list =  Get-Content .\filelist.txt
foreach ($file in $file_list) {
    Write-Output "Reading file $file"
    Get-Content $file
}

$ErrorActionPreference 值设置为默认值 Continue 时,运行上面修改后的代码的行为将与以前不同。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

从上面结果的屏幕截图中可以看到,脚本能够读取列表中的前五个文件,但是当它尝试读取文件 File_6.txt 时,会返回错误,因为找不到该文件。然后,脚本终止,并且不会读取其余文件。

$ErrorActionPreference 值仅在当前 PowerShell 会话中有效。一旦启动新的 PowerShell 会话,它就会重置为默认值。

ErrorAction 通用参数

如果 $ErrorActionPreference 值应用于 PowerShell 会话,则 ErrorAction 参数应用于支持通用参数的任何 cmdlet。 ErrorAction 参数接受与 $ErrorActionPreference 变量相同的值。

ErrorAction 参数值优先于 $ErrorActionPreference 值。

让我们返回并使用前面示例中的相同代码。但是,这一次,ErrorAction 参数被添加到 Get-Content 行中。

# Set the $ErrorActionPreference value to default (CONTINUE)
$ErrorActionPreference = "CONTINUE"
$file_list =  Get-Content .\filelist.txt
foreach ($file in $file_list) {
    Write-Output "Reading file $file"
		# Use the -ErrorAction common parameter
		Get-Content $file -ErrorAction STOP
}

运行修改后的代码后,您会看到即使 $ErrorActionPreference 设置为 Continue,脚本在遇到错误时仍然会终止。由于 Get-Content 中的 PowerShell ErrorAction 参数值设置为 STOP,脚本终止。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

使用 PowerShell Try Catch 块

至此,您已经了解了 PowerShell 错误以及 $ErrorActionPreference 变量和 PowerShell ErrorAction 参数的工作原理。现在,是时候了解一些好东西了 - PowerShell Try Catch Final 块。

PowerShell try catch 块(和可选的 finally 块)是一种围绕一段代码撒网并捕获返回的任何错误的方法。

下面的代码显示了 Try 语句的语法。

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

Try 块包含您希望 PowerShell “尝试”并监视错误的代码。如果 Try 块中的代码遇到错误,则会将该错误添加到 $Error 变量中,然后传递给 Catch 块。

Catch 块包含从 Try 块收到错误时要执行的操作。 Try 语句中可以有多个 Catch 块。

Finally 块包含位于 Try 语句末尾的代码。无论错误是否未计数,该块都会运行。

使用 PowerShell ErrorAction 捕获非特定错误(Catch-All)

一个简单的 Try 语句包含一个 Try 和一个 Catch 块。 Finally 块是可选的。

例如,要捕获非特定异常,Catch 参数应为空。下面的示例代码使用与 $ErrorActionPreference Variable 部分中使用的脚本相同的脚本,但修改为使用 Try Catch 块。

从下面的代码中可以看到,这一次,foreach 语句被包含在 Try 块内。然后,Catch 块包含在发生错误时显示字符串 An Error Occurred 的代码。 Finally 块中的代码仅清除 $Error 变量。

$file_list = Get-Content .\filelist.txt
try {
    foreach ($file in $file_list) {
        Write-Output "Reading file $file"
        Get-Content $file -ErrorAction STOP
    }
}
catch {
    Write-Host "An Error Occured" -ForegroundColor RED
}
finally {
    $Error.Clear()
}

上面的代码在 PowerShell 中运行后,将给出如下所示的输出。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

上面的输出显示脚本遇到错误,运行 Catch 块内的代码,然后终止。

错误被处理了,这就是错误处理的重点。但是,显示的错误太笼统了。要显示更具描述性的错误,您可以访问由 Try 块传递的错误的 Exception 属性。

下面的代码经过修改,特别是 Catch 块内的代码,以显示沿管道传递的当前错误的异常消息 - $PSItem.Exception.Message

$file_list = Get-Content .\filelist.txt
try {
    foreach ($file in $file_list) {
        Write-Output "Reading file $file"
        Get-Content $file -ErrorAction STOP
    }
}
catch {
    Write-Host $PSItem.Exception.Message -ForegroundColor RED
}
finally {
    $Error.Clear()
}

这次,当运行上面修改后的代码时,显示的消息更具描述性。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

捕获特定错误

有时,包罗万象的错误处理并不是最合适的方法。也许,您希望脚本执行取决于遇到的错误类型的操作。

如何确定错误类型?通过检查最后一个错误的 Exception 属性的 TypeName 值。例如,要查找上一示例中的错误类型,请使用以下命令:

$Error[0].Exception | Get-Member

上面代码的结果将类似于下面的屏幕截图。如您所见,显示了 TypeName 值 - System.Management.Automation.ItemNotFoundException

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

现在您知道了需要拦截的错误类型,请修改代码以专门捕获它。正如您从下面修改后的代码中看到的,现在有两个 Catch 块。第一个 Catch 块拦截特定类型的错误 (System.Management.Automation.ItemNotFoundException)。相反,第二个Catch 块包含通用的、包罗万象的错误消息。

$file_list = Get-Content .\filelist.txt
try {
    foreach ($file in $file_list) {
        Write-Output "Reading file $file"
        Get-Content $file -ErrorAction STOP
    }
}
catch [System.Management.Automation.ItemNotFoundException]{
    Write-Host "The file $file is not found." -ForegroundColor RED
}
catch {
    Write-Host $PSItem.Exception.Message -ForegroundColor RED
}
finally {
    $Error.Clear()
}

下面的屏幕截图显示了上面修改后的代码的输出。

[玩转系统] 如何使用 PowerShell Try Catch 块提升游戏体验

结论

在本文中,您了解了 PowerShell 中的错误、其属性以及如何确定错误的特定类型。您还了解了 $ErrorActionPreference 变量和 PowerShell ErrorAction 参数如何影响 PowerShell 处理非终止错误的方式之间的差异。

您还了解了如何使用 PowerShell Try Catch Final 块来执行错误处理,无论是针对特定错误还是针对所有错误。

本文中显示的示例仅演示了 Try Catch Final 块如何工作的基础知识。我希望您在本文中获得的知识应该为您在脚本中应用错误处理奠定基础。

进一步阅读

  • About_Try_Catch_Finally
  • 关于自动变量
  • 回归基础:PowerShell foreach 循环
  • 回归基础:了解 PowerShell 对象

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯