how to prevent external script from terminating your script with break statement
我正在调用外部.ps1文件,该文件在某些??错误情况下包含
为了回答这个问题,假设不能更改外部.ps1文件的源代码(由他人创作并在运行时插入)。
我想要的是可能的吗,还是脚本的编写者只是在外部调用时不考虑打得好?
编辑:提供以下示例。
在badscript.ps1中:
1 2 3 4 | if((Get-Date).DayOfWeek -ne"Yesterday"){ Write-Warning"Sorry, you can only run this script yesterday." break } |
在myscript.ps1中:
1 2 | .\badscript.ps1 Write-Host"It is today." |
我想获得的结果是看到badscript.ps1发出的警告,并继续在myscript.ps1中继续我的声明。我理解break语句为何导致"今天"。永远不会被打印,但是我想找到一种解决方法,因为我不是badscript.ps1的作者。
编辑:将标题从" powershell tr??y / catch不能捕获break语句"更新为"如何防止外部脚本使用break语句终止脚本"。提到try / catch的确是解决实际问题的一个失败解决方案,新标题可以更好地反映这一问题。
从脚本内部运行单独的PowerShell进程以调用外部文件,最终成为了一种足以满足我需要的解决方案:
我知道你来自哪里。可能最简单的方法是将脚本作为工作推送,然后等待结果。如果需要,您甚至可以在完成后用Receive-Job回显结果。
因此,考虑到上面有错误的脚本,以及此脚本文件将其调用:
1 2 3 4 5 6 7 | $path = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent $start = Start-Job -ScriptBlock { ."$using:Path\badScript.ps1" } -Name"BadScript" $wait = Wait-Job -Name"BadScript" -Timeout 100 Receive-Job -Name"BadScript" Get-Command -Name"Get-ChildItem" |
这将在作业中执行错误的脚本,等待结果,回显结果,然后继续执行其中的脚本。
这可以包装在您可能需要调用的所有脚本的函数中(出于安全考虑。
这是输出:
1 2 3 4 5 | WARNING: Sorry, you can only run this script yesterday. CommandType Name Version Source ----------- ---- ------- ------ Cmdlet Get-ChildItem 3.1.0.0 Microsoft.PowerShell.Management |
将中断放回其所属的循环(包括开关)中。
1 2 | foreach($i in 1) { ./badscript.ps1 } 'done' |
在about_Break文档中说
PowerShell does not limit how far labels can resume execution. The
label can even pass control across script and function call
boundaries.
这让我开始思考:"我该如何欺骗这种愚蠢的语言设计选择?"。答案是创建一个小的
。 naughtyBreak.ps1
1 2 | Write-Host"NaughtyBreak about to break" break |
。 OuterScript.ps1
1 2 3 4 5 6 7 8 9 | switch ('dummy') { default {. aughtyBreak.ps1}} Write-Host"After switch() {NaughtyBreak}" . aughtyBreak.ps1 Write-Host"After plain NaughtyBreak" |
然后,当我们调用OuterScript.ps1时,我们得到
1 2 3 | NaughtyBreak about to break After switch() {NaughtyBreak} NaughtyBreak about to break |
请注意,在对嵌入在交换机中的NaughtyBreak.ps1的调用之后,OuterScript.ps1可以正确恢复,但是在直接调用NaughtyBreak.ps1时被毫不客气地杀死了。