Powershell tr​​y-catch ...其他?

标签 powershell try-catch

我在 Powershell 中了解 try-catch-finally,但是是否有类似于 Python 的“else”子句的东西,其中代码仅在没有错误的情况下运行?

我正在编写一个在经常出现故障的网站上使用 invoke-webRequest 的脚本。我使用 try-catch 来捕获 HTTP 错误。
我还希望只有在 invoke-webRequest 命令成功完成时才运行一段代码。

try{
    invoke-WebRequest -URI 'http://flakywebsite.com/site1' -Method GET
    invoke-WebRequest -URI 'http://flakywebsite.com/site2' -Method GET
    invoke-WebRequest -URI 'http://flakywebsite.com/site3' -Method GET
    }
catch{
    "This line will execute only if there is an error in the try block"
    }
else{
    "This line will execute only if there is NOT an error in the try block"
    }
finally{
    "This code will run regardless of whether there is or is not an error in the try block."
    }

我有这个解决方法。它使用 catch block 将通知附加到 $Error 变量:
try{
    invoke-WebRequest -URI 'http://flakywebsite.com/site1' -Method GET
    invoke-WebRequest -URI 'http://flakywebsite.com/site2' -Method GET
    invoke-WebRequest -URI 'http://flakywebsite.com/site3' -Method GET
    }
catch{
    $Error.add("An error occurred in the try loop."}
    }
if($Error[-1] -ne "An error occurred in the try loop."){
    "This code will run only if there is NOT an error in the try block.
    }

这行得通,但它非常丑陋。在 Powershell 中有没有更好的方法来做到这一点?

最佳答案

不,从 v7 开始,遗憾的是 PowerShell 不提供类似 Python 的 else子句作为 try 的一部分/catch陈述。

  • 您可以在 PowerShell Core GitHub repository 中创建功能请求.


  • 一种选择是将 only-if-not-catch 代码放在 try 的底部 block , 在可能失败的命令之后 - 见 Zafer Balkan's helpful answer .

    如果这是不希望的 , 我建议使用以下成语作为 解决方法 :
    # Make sure that even normally non-terminating errors trigger the
    # `catch` block below.
    # Note that the *first* error that occurs in the `try` block
    # will jump to the `catch` block right away - subsequent commands won't execute.
    $ErrorActionPreference = 'Stop'
    
    # Save the count of errors currently recorded in the automatic $Errors collection.
    $errCountBefore = $Error.Count
    
    try {
    
        invoke-WebRequest -URI 'http://flakywebsite.com/site1' -Method GET
        invoke-WebRequest -URI 'http://flakywebsite.com/site2' -Method GET
        invoke-WebRequest -URI 'http://flakywebsite.com/site3' -Method GET
    
    }
    catch {
        # Write a custom error to the $Error collection, as the *first* 
        # (most recent) item.
        # Note: If you want the error to also *display*, use `-ErrorAction Continue`.
        Write-Error -ErrorAction SilentlyContinue "An error occurred in the try loop: $_"
    }
    
    if ($errCountBefore -eq $Error.Count) { # No errors occurred.
      "This code will run only if there is NOT an error in the try block."
    }
    

    注:如果您没有在 catch 中写入错误 block ,使用自定义 [bool]变量如 $caught 您设置为 $true在您的 catch block ,然后测试 if (-not $caught) .

    至于你尝试了什么 :

    $Error.add("An error occurred in the try loop."}



    你不应该直接写信给 $Error (这使得以下几点没有实际意义:不要添加字符串,也不要附加到它存储的错误集合中),原因如下:

    $Error就是所谓的automatic variable 在 PowerShell 中,这通常意味着 PowerShell 自己管理它 ,并且用户代码不应该直接修改它。

    关于 $Error 的唯一异常(exception)是你可能想清除迄今为止在 session 中累积的错误集合,使用 $Error.Clear()
    否则,PowerShell 管理 $Error如下:
  • 任何错误都会自动登录$Error ,按时间倒序排列(最近的在前)。
  • 唯一的异常(exception)是使用 -ErrorAction Ignore 调用的命令。和来自外部程序的 stderr 输出。
  • $Error仅包含提供有关每个错误的结构化详细信息的错误记录对象(类型为 System.Management.Automation.ErrorRecord 的实例)。

  • 因此,为了在 $Error 中记录错误,您需要执行所有代码是使用 Write-Error 将错误写入错误流,或使用 Throw 引发脚本终止错误声明 - PowerShell 会将每个错误包装在 System.Management.Automation.ErrorRecord 中如有必要,添加到 $Error 前面按时间倒序排列。

    关于Powershell tr​​y-catch ...其他?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58346168/

    相关文章:

    PowerShell 在 Get-ComputerInfo 的行输出开头添加破折号

    windows - Windows Powershell 中的 mklink 是什么?

    string - PowerShell,管道兼容的 Select-String 函数

    c# - 重新抛出异常困难——异常使程序崩溃而不是重新抛出

    r - 如何将警告()输出到字符串

    powershell - Powershell脚本输出到变量-捕获Write-Host输出

    powershell - 在多个父文件夹中使用 PowerShell 创建子文件夹

    java - 为什么我的代码绕过了 else if 语句?

    java - 每次输入不正确时如何返回 "try"代码(Java中)?

    powershell - Powershell管道中的错误处理