在PowerShell中终止脚本

我一直在寻找一种方法来终止PowerShell(PS1)脚本,当一个函数内发生不可恢复的错误。 例如:

function foo() { # Do stuff that causes an error $host.Exit() } 

当然,没有$host.Exit()这样的东西。 有$host.SetShouldExit() ,但这实际上closures了控制台窗口,这不是我想要的。 我所需要的东西等同于Python的sys.exit() ,它将简单地停止当前脚本的执行,而不需要进一步的介绍。

编辑:是的,这只是exit 。 咄。

你应该使用exit关键字 。

我意识到这是一个旧的post,但我发现自己回到这个线程很多,因为它是search这个主题的热门search结果之一。 但是,当我由于矛盾的信息而来到这里时,我总是比较困惑。 最终,我总是必须执行我自己的testing来弄清楚。 所以这次我会发表我的发现。

TL; DR大多数人会希望使用Exit来终止正在运行的脚本。 但是,如果您的脚本仅仅是声明函数以便稍后在shell中使用,那么您将希望在所述函数的定义中使用Return

退出与回报vsrest

  • 退出:这将“退出”当前正在运行的上下文。 如果你从脚本调用这个命令,它将退出脚本。 如果你从shell中调用这个命令,它将会退出shell。

    如果一个函数调用了Exit命令,它将会退出正在运行的上下文。所以如果这个函数只在运行脚本中被调用,它将会退出该脚本。 然而,如果你的脚本只声明了这个函数,以便它可以从当前shell中使用,并且你从shell运行该函数,那么它将退出shell,因为shell是连续执行Exit命令的函数的上下文。

    注意:默认情况下,如果右键单击脚本以在PowerShell中运行脚本,脚本运行完毕后,PowerShell将自动closures。 这与Exit命令或脚本中的其他内容无关。 这只是使用此特定方法运行脚本的脚本的默认PowerShell行为。 batch file和命令行窗口也是如此。

  • 返回:这将返回到前一个呼叫点。 如果你从一个脚本(在任何函数之外)调用这个命令,它将返回到shell。 如果你从shell调用这个命令,它将返回到shell(这是从shell运行的单个命令的前一个调用点)。 如果你从一个函数调用这个命令,它将返回到函数被调用的地方。

    在返回的调用点之后执行任何命令将从该点继续。 如果一个脚本是从shell调用的,并且包含任何函数之外的Return命令,那么当它返回到shell时,没有更多的命令可以运行,从而使得以这种方式使用的ReturnExit基本相同。

  • rest:这将打破循环和切换个案。 如果您在不处于循环或切换大小写的情况下调用此命令,则会跳出脚本。 如果你在一个嵌套在循环中的循环中调用Break ,它只会跳出它所调用的循环。

    Break还有一个有趣的特性,你可以用一个标签作为循环的前缀,然后即使在标签循环中的几个嵌套组中调用了Break命令,也可以跳出标签循环。

     While ($true) { # Code here will run :myLabel While ($true) { # Code here will run While ($true) { # Code here will run While ($true) { # Code here will run Break myLabel # Code here will not run } # Code here will not run } # Code here will not run } # Code here will run } 

Exit也将退出PowerShell。 如果您希望从当前的函数或脚本中“跳出”,请使用Break 🙂

 If ($Breakout -eq $true) { Write-Host "Break Out!" Break } ElseIf ($Breakout -eq $false) { Write-Host "No Breakout for you!" } Else { Write-Host "Breakout wasn't defined..." } 

写入错误是针对非终止错误, 抛出是为了终止错误

Write-Error cmdlet声明一个非终止错误。 默认情况下,错误将在错误stream中发送到要显示的主机程序以及输出。

非终止错误会向错误stream写入错误,但不会停止命令处理。 如果在input项集合中的一个项目上声明了非终止错误,则该命令继续处理集合中的其他项目。

要声明终止错误,请使用Throw关键字。 有关更多信息,请参阅about_Throw( http://go.microsoft.com/fwlink/?LinkID=145153 )。

我认为你正在寻找Return而不是Break 。 中断通常用于循环,只能从最内层的代码块中断开。 使用Return退出一个函数或脚本。

终止此过程,并为底层操作系统提供指定的退出代码。

https://msdn.microsoft.com/en-us/library/system.environment.exit%28v=vs.110%29.aspx

[Environment]::Exit(1)

这将允许您退出一个特定的退出代码,可以从调用者拿起。

抛出exception会很好,特别是如果你想澄清错误的原因:

 throw "Error Message" 

这将产生一个终止错误。

可能是使用“陷阱”更好。 PowerShell陷阱指定发生终止或错误时运行的代码块。 types

 Get-Help about_trap 

了解更多关于陷阱的声明。

我用这个来重新运行一个程序。 我不知道这是否有帮助,但是这只是一个简单的陈述,只需要两个不同的条目。 它在PowerShell中为我工作。

 $rerun = Read-Host "Rerun report (y/n)?" if($rerun -eq "y") { Show-MemoryReport } if($rerun -eq "n") { Exit } 

不知道这是否有帮助,但我相信这将是在你运行它之后终止一个程序。 但是,在这种情况下,每个定义的input都需要列出和分类的输出。 您也可以通过退出调用新的提示行,并以此方式终止程序。

我巧合地发现Break <UnknownLabel> (例如简单的Break Script其中标签Script不存在 )似乎突破了整个脚本(甚至在一个函数内),并使主机保持活动状态。
这样你就可以创build一个函数,在不知道当前作用域(和创build标签)的情况下,从任何地方(例如recursion循环)中断脚本:

 Function Quit($Text) { Write-Host "Quiting because: " $Text Break Script }