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

[玩转系统] 关于陷阱

作者:精品下载站 日期:2024-12-14 02:17:50 浏览:11 分类:玩电脑

关于陷阱


简短描述

描述处理终止错误的关键字。

详细描述

终止错误会停止语句的运行。如果 PowerShell 不以某种方式处理终止错误,PowerShell 也会停止运行当前管道中的函数或脚本。在其他语言(例如 C#)中,终止错误称为异常。

trap 关键字指定发生终止错误时要运行的语句列表。 trap 语句可以通过以下方式处理终止错误:

  • 处理 trap 语句块并继续执行包含 trap 的脚本或函数后显示错误。此行为是默认行为。

    笔记

    当从属脚本块(例如 if 语句或 foreach 循环)中发生终止错误时,将运行 trap 块中的语句并在从属脚本块之外的下一条语句处继续执行。

  • trap 语句中使用 break 显示错误并中止包含 trap 的脚本或函数的执行。

  • 消除错误,但通过在 trap 语句中使用 continue 继续执行包含 trap 的脚本或函数。

trap 的语句列表可以包含多个条件或函数调用。 trap 可以写入日志、测试条件,甚至运行另一个程序。

句法

trap 语句具有以下语法:

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

trap 语句包含发生终止错误时要运行的语句列表。 trap 语句由 trap 关键字(可选地后跟类型表达式)和包含捕获错误时要运行的语句列表的语句块组成。类型表达式细化了陷阱捕获的错误类型。

一个脚本或命令可以有多个 trap 语句。 trap 语句可以出现在脚本或命令中的任何位置。

捕获所有终止错误

当发生终止错误且未在脚本或命令中以其他方式处理时,PowerShell 会检查处理该错误的 trap 语句。如果存在 trap 语句,PowerShell 会继续运行 trap 语句中的脚本或命令。

以下示例是一个最小的 trap 语句:

trap { 'Error found.' }

trap 语句捕获任何终止错误。

在以下示例中,该函数包含导致运行时错误的无意义字符串。

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

TrapTest

运行此函数将返回以下输出:

Error found.
nonsenseString:
Line |
   3 |      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.

以下示例包含一个 trap 语句,该语句使用 $_ 自动变量显示错误:

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 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.

这很重要

trap 语句可以定义在给定脚本块内的任何位置,但始终适用于该脚本块中的所有语句。在运行时,块中的 trap 语句在执行任何其他语句之前定义。在 JavaScript 中,这称为提升。这意味着 trap 语句适用于该块中的所有语句,即使执行尚未超过它们定义的点。例如,在脚本末尾定义陷阱并在第一个语句中抛出错误仍然会触发该陷阱

捕获特定错误

一个脚本或命令可以有多个 trap 语句。可以定义陷阱来处理特定的错误。

以下示例是捕获特定错误 CommandNotFoundExceptiontrap 语句:

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

当函数或脚本遇到与已知命令不匹配的字符串时,此trap 语句将显示Command error trapped 字符串。运行 trap 语句列表后,PowerShell 将错误对象写入错误流,然后继续执行脚本。

PowerShell 使用 .NET 异常类型。以下示例指定 System.Exception 错误类型:

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

CommandNotFoundException 错误类型继承自 System.Exception 类型。该语句捕获未知命令引发的任何错误。它还捕获其他错误类型。

您可以通过检查错误对象来找到错误的异常类型。以下示例显示如何获取会话中最后一个错误的异常的全名:

nonsenseString
$Error[0].Exception.GetType().FullName
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.

System.Management.Automation.CommandNotFoundException

脚本中可以有多个 trap 语句。只有一个 trap 语句可以捕获每种错误类型。当发生终止错误时,PowerShell 会从当前执行的脚本块开始搜索具有最具体匹配的陷阱

以下脚本示例包含错误。该脚本包含一个捕获任何终止错误的通用 trap 语句和一个指定 CommandNotFoundException 类型的特定 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 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.

由于 PowerShell 无法将 nonsenseString 识别为 cmdlet 或其他项,因此它会返回 CommandNotFoundException 错误。特定的trap语句捕获此终止错误。

以下脚本示例包含相同的 trap 语句,但有不同的错误:

trap { 'Other terminating error trapped' }
trap [System.Management.Automation.CommandNotFoundException] {
    'Command error trapped'
}
1/$null

运行此脚本会产生以下结果:

Other terminating error trapped
RuntimeException:
Line |
   5 |  1/$null
     |  ~~~~~~~
     | Attempted to divide by zero.

尝试除以零不会产生 CommandNotFoundException 错误。另一个trap 语句捕获任何终止错误,捕获被零除错误。

在脚本块中捕获错误

默认情况下,当引发终止错误时,执行将转移到 trap 语句。运行trap 块后,控制返回到错误位置之后的下一个语句块。

例如,当 foreach 语句中发生终止错误时,将运行 trap 语句,并在 foreach 块之后的下一个语句处继续执行,不在 foreach 块内。

trap { 'An error occurred!'}
foreach ($x in 3..-1) {
       "1/$x = "
       "`t$(1/$x)"
}
'after loop'
1/3 =
        0.333333333333333
1/2 =
        0.5
1/1 =
        1
1/0 =
An error occurred!
RuntimeException:
Line |
   4 |         "`t$(1/$x)"
     |              ~~~~
     | Attempted to divide by zero.
after loop

在输出中,您可以看到循环一直持续到最后一次迭代。当脚本尝试将 1 除以 0 时,PowerShell 会抛出终止错误。该脚本会跳过 foreach 脚本块的其余部分,运行 try 语句,并在 foreach 脚本块之后继续。

捕获错误和范围

如果终止错误发生在与 trap 语句相同的脚本块中,PowerShell 将运行由 trap 定义的语句列表。从错误后的语句处继续执行。如果 trap 语句与错误位于不同的脚本块中,则继续执行与 trap 语句位于同一脚本块中的下一个语句。

例如,如果函数中发生错误,并且 trap 语句位于该函数中,则脚本将继续执行下一条语句。以下脚本包含一个错误和一个 trap 语句:

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

function1

运行此脚本会产生以下结果:

An error:
NonsenseString:
Line |
   3 |      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.
function1 was completed

函数中的 trap 语句捕获错误。显示消息后,PowerShell 恢复运行该函数。请注意,Function1trap 语句之后完成。

将此行为与以下示例进行比较,该示例具有相同的错误和 trap 语句。在此示例中,trap 语句出现在函数外部:

function function2 {
    NonsenseString
    'function2 was completed'
}

trap { 'An error:' }

function2

运行 Function2 函数会产生以下结果:

An error:
NonsenseString:
Line |
   2 |      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.

在此示例中,function2 was Completed 命令未运行。在这两个示例中,终止错误都发生在函数内。然而,在此示例中,trap 语句位于函数外部。 trap 语句运行后,PowerShell 不会返回到该函数。

警告

当为同一错误条件定义多个陷阱时,将使用按词法定义的第一个陷阱(脚本块中的最高位置)。

在以下示例中,仅运行带有 whoops 1trap

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

这很重要

trap 语句的作用域为它的编译位置。如果函数或点源脚本内有 trap 语句,当函数或点源脚本退出时,其中的所有 trap 语句都会被删除。

使用 break 和 continue 关键字

您可以在 trap 语句中使用 breakcontinue 关键字来确定脚本或命令在终止错误后是否继续运行。

如果在 trap 语句列表中包含 break 语句,PowerShell 将停止该函数或脚本。以下示例函数在 trap 语句中使用 break 关键字:

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.

由于 trap 语句包含 break 关键字,因此该函数不会继续运行,并且 Functioncompleted 行也不会运行。

如果您在 trap 语句中包含 continue 关键字,PowerShell 将在导致错误的语句之后恢复,就像没有 break 或 继续。但是,使用 continue 关键字时,PowerShell 不会将错误写入错误流。

以下示例函数在 trap 语句中使用 continue 关键字:

function ContinueExample {
    trap {
        'Error trapped'
        continue
    }
    foreach ($x in 3..-1) {
       "1/$x = "
       "`t$(1/$x)"
    }
    'End of function'
}

ContinueExample
1/3 =
        0.333333333333333
1/2 =
        0.5
1/1 =
        1
1/0 =
Error trapped
End of function

函数在捕获错误后恢复,并且 End of function 语句运行。没有错误被写入错误流。

笔记

trap 语句提供了一种确保处理脚本块内的所有终止错误的方法。要进行更细粒度的错误处理,请使用 try/catch 块,其中使用 catch 语句定义陷阱。 catch 语句仅适用于关联的 try 语句内的代码。有关详细信息,请参阅 about_Try_Catch_Finally。

参见

  • about_Break
  • 关于_继续
  • about_范围
  • about_Throw
  • about_Try_Catch_Finally

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

取消回复欢迎 发表评论:

关灯