在PowerShell中终止脚本

时间:2010-01-07 17:42:15

标签: powershell

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

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

当然没有$host.Exit()之类的东西。有$host.SetShouldExit(),但这实际上关闭了控制台窗口,这不是我想要的。我需要的是与Python的sys.exit()相当的东西,只需停止执行当前脚本而不需要进一步执行。

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

10 个答案:

答案 0 :(得分:517)

我意识到这是一篇很老的帖子,但我发现自己回到这个帖子很多,因为它是搜索这个主题时的顶级搜索结果之一。但是,当我来到时,由于信息冲突,我总是更加困惑。最终,我总是要进行自己的测试来弄明白。所以这次我会发布我的发现。

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

退出vs返回与中断

  • 退出:这将"退出"当前运行的上下文。如果从脚本调用此命令,它将退出脚本。如果从shell调用此命令,它将退出shell。

    如果函数调用Exit命令,它将退出它正在运行的任何上下文。因此,如果仅从正在运行的脚本中调用该函数,它将退出该脚本。但是,如果您的脚本只是声明了该函数,以便可以从当前shell使用它并从shell运行该函数,它将退出shell,因为shell是函数包含Exit的上下文命令正在运行。

    注意:默认情况下,如果右键单击脚本在PowerShell中运行它,则一旦脚本运行完毕,PowerShell将自动关闭。这与Exit命令或脚本中的任何其他内容无关。对于使用此特定运行脚本的方法运行的脚本,它只是一个默认的PowerShell行为。批处理文件和命令行窗口也是如此。

  • 返回:这将返回上一个呼叫点。如果从脚本(任何函数外部)调用此命令,它将返回到shell。如果从shell调用此命令,它将返回到shell(这是从shell运行的单个命令的先前调用点)。如果从函数调用此命令,它将返回到调用函数的位置。

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

  • 中断:这将打破循环和切换案例。如果你在没有循环或切换的情况下调用此命令,它将突破脚本。如果你在一个嵌套在循环中的循环中调用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
    }
    

答案 1 :(得分:334)

您应该使用the exit keyword

答案 2 :(得分:75)

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..."
}

答案 3 :(得分:45)

Write-Error用于非终止错误,throw用于终止错误

  

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

     

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

     

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

答案 4 :(得分:25)

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

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

[Environment]::Exit(1)

这将允许您退出特定的退出代码,该代码可以从调用者处获取。

答案 5 :(得分:24)

我认为您正在寻找Return而不是Break。 Break通常用于循环,只从最里面的代码块中断。使用Return退出函数或脚本。

答案 6 :(得分:20)

如果您想澄清错误原因,抛出异常将会很好:

throw "Error Message"

这将产生终止错误。

答案 7 :(得分:12)

可能最好使用“陷阱”。 PowerShell陷阱指定在发生终止或错误时要运行的代码块。型

Get-Help about_trap

了解有关陷阱声明的更多信息。

答案 8 :(得分:5)

我巧合地发现Break <UnknownLabel>(例如只是Break Script标签Script不存在)似乎突破了整个脚本(甚至在一个函数内)并使主机保持活力 这样你就可以在不知道当前范围(和创建标签)的情况下创建一个从任何地方(例如递归循环)中断脚本的函数:

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

答案 9 :(得分:3)

我用它来重新运行一个程序。我不知道它是否会有所帮助,但这是一个简单的if语句只需要两个不同的条目。它对我来说很有用。

$rerun = Read-Host "Rerun report (y/n)?"

if($rerun -eq "y") { Show-MemoryReport }
if($rerun -eq "n") { Exit }

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