【问题标题】:Handle keyboard interrupt, execute end block处理键盘中断,执行结束块
【发布时间】:2019-04-24 00:58:03
【问题描述】:

我有一个处理文件列表的 powershell 函数。我为此使用了beginprocessend 块:

begin {
    # prepate some stuff
}
process {
    # process each file
}
end {
    # clean up
}

现在,当我按下 Ctrl+C 时,整个脚本就在它所在的位置终止。对于流程部分来说,这并不是真正的问题,因为它只会对最后一个命令进行永久性更改。

不过,我仍然想执行 end 块中的内容以稍微清理一下,并打印一些有关已成功处理的文件的统计信息。

是否有一种干净的方法来捕获键盘中断,同时保持开始/处理/结束结构?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    执行此操作的一种方法是在脚本块运行时禁用 Ctrl-C 的处理作为中断。当然,您必须手动检查它是否会中断,但它应该保证结束块运行

    begin { 
      [Console]::TreatControlCAsInput = $true
    }
    process {
      # Maybe check for Ctrl-C here to terminate processing
    }
    end { 
      [Console]::TreatControlCAsInput = $false
    }
    

    为了以非阻塞方式检查 Ctr-C 作为输入,您可以执行以下操作

    if ([Console]::KeyAvailable) {
      $key = [Console]::ReadKey($true)
      if ($key.key -eq "C" -and $key.modifiers -eq "Control") { 
        # Clean up and exit
      }
    }
    

    【讨论】:

    • 嗯,很有趣。您能否扩展 “也许在此处检查 Ctrl-C 以终止处理” 部分?如果它被视为输入,我如何检查 Ctrl-C 然后在里面?以及如何在不引发错误的情况下停止处理(这也会跳过结束块 - 或不)?
    • @poke 我添加了一些示例代码来检查 ctr-c 作为输入。至于结束块,可能最好的解决方案是将结束块处理分解为另一个函数。然后,如果在process 块中按下ctrl-c,您可以直接调用它并退出循环并通过end 无条件调用它
    【解决方案2】:

    当脚本由于以下任何一种情况而终止时,try/catch/finally 块集的“finally”部分仍会执行:

    • Ctrl+C 被按下(随时)
    • 在 catch 部分中遇到了 Exit 关键字
    • 发生致命错误(在“finally”部分本身之外)

    把你所有的清理工作都放在那里。无论发生什么其他事情,它都会运行(编辑:除非“finally”块本身抛出错误)。

    (进一步编辑:我将您的原始标记留在那里以供空间参考 - 它们现在已被删除,因此文字复制/粘贴不应包含无效关键字。

    try { # begin, and/or process
    }
    catch { # optionally handle errors
    }
    finally { # clean up 
    }
    

    您可以将准备步骤和实际处理都放在一个“try”块中,或者您可以创建其中两个块 - 无论哪种方式,“try”和“catch”都是必需的,“finally”是可选的。

    【讨论】:

    • 如果这可行,那就太好了,但它似乎不是有效的语法。我收到end 无法识别的错误;而且我不认为begin/process/finally 可能包含在任何东西中,因为在那里使用begin 已经引发错误,导致catch 立即执行。
    • 澄清了答案,以便可以复制/粘贴。
    • 我知道正常的异常处理是如何工作的。但是,这并不能处理管道……
    猜你喜欢
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    • 2010-11-27
    • 2012-01-11
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多