【问题标题】:Powershell - terminate command when it outputs a certain stringPowershell - 在输出某个字符串时终止命令
【发布时间】:2020-04-21 15:41:34
【问题描述】:

我有一个在 PowerShell 中运行的命令,它会意外出错(每当网络连接饱和时,它就会出错)

出现错误后,它将不再按预期运行,但会继续运行。该错误也不会像标准文本一样打印为错误。

我想让命令在循环中运行,以检测何时出错,然后将其终止并重新启动,但我无法找到任何有关实时解析命令输出的信息。

例如:foo.ps1 每秒输出一个数字,但会随机开始每秒输出一次“ERROR: CONNECTION SATURATED”。如何创建一个循环来检测、终止进程并重新启动它?

编辑: command erroring 这就是命令错误的样子。如您所见,错误 (Warning: ring buffer overflow!!!) 打印为标准输出,而不是错误。

【问题讨论】:

    标签: powershell loops error-handling command


    【解决方案1】:

    不用说,您不能使用标准的 PowerShell 错误处理机制,因为您的命令既不会引发异常,也不会写入错误流。因此,您必须在生成命令时对其输出(即异步)进行解析。

    运行命令并异步访问其输出的最简单方法是使用作业。因此,以下脚本应该可以完成您的要求:

    param(
        # Specifies the commands to run in the job.
        [ScriptBlock] $ScriptBlock,
    
        # Specifies the text for which to search in each line of the output.
        [string] $Pattern = '^\s*(Warning|Error)',
    
        # Specifies how long to sleep in seconds between output searches.   
        [int] $Seconds = 1
    )
    
    while ($true) {
        $job = Start-Job $ScriptBlock
        while ($job.State -eq 'Running') {
            $output = Receive-Job $job
            if ($output -match $Pattern) {
                break
            }
            Start-Sleep $Seconds
        }
        Stop-Job $job
    }
    

    根据您的要求,您可能还想:

    • 扩展可接受的job states 集合。
    • 如果遇到某些特定的作业状态或其他输出模式,则完全终止脚本(即重新启动作业)。

    【讨论】:

      【解决方案2】:

      这很奇怪,但是“select -first 1”在找到答案时会杀死管道。像这样只会运行5秒。

      & { foreach ($i in 1..10) { $i; sleep 1 } } | where { $_ -eq 5 } | 
        select -first 1  
      

      【讨论】:

        【解决方案3】:

        你可以使用trap关键字来检测错误并处理它,即

        function Test {
            Write-Host "Doing something..."
            trap {
                Write-Host "Error found:"
                break
            }
        
            Write-Host "Code should not reach here"
        }
        

        要捕获特定异常,您可以指定要捕获的内容

        ...
        trap [TheExceptionYouWantToCatch]{
        ...
        }
        ...
        

        【讨论】:

        • 我尝试过使用陷阱,但该命令给出的“错误”并不是一个实际的可陷阱错误,它只是常规标准输出,将其与常规行为区分开来的唯一方法是它总是相同的文本,这与正常行为不同(确切的文本是Ring buffer overflow!!!,该字符串永远不会出现在正常行为中)
        • 我不必在捕获标准输出方面做太多工作,但快速搜索让我找到了这个(stackoverflow.com/a/11549817/3986395) 答案,也许它可以帮助您将标准输出转换为try/@ 987654326@块
        猜你喜欢
        • 1970-01-01
        • 2021-10-16
        • 1970-01-01
        • 1970-01-01
        • 2021-09-10
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多