在PowerShell中终止脚本

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

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

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

编辑:对,就是exit。咄。

1240115 次浏览

也许用“陷阱”更好。PowerShell trap指定当发生终止或错误时要运行的代码块。类型

Get-Help about_trap

了解更多关于trap语句的信息。

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

我认为你正在寻找Return而不是Break。Break通常用于循环,并且只从最内部的代码块中中断。使用Return命令退出函数或脚本。

写错误用于非终止错误,用于终止错误

写错误cmdlet声明了一个非终止错误。默认情况下, 错误以错误流的形式发送给主机程序

非终止错误将错误写入错误流,但是 它们不会停止命令处理。如果非终止错误为 命令在输入项集合中的一个项上声明

.继续处理集合中的其他项

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

我知道这是一个老帖子,但我发现自己经常回到这个帖子,因为它是搜索这个主题时的头号搜索结果之一。然而,我总是离开比我来的时候更困惑,因为相互矛盾的信息。最终,我总是不得不执行自己的测试来弄清楚。所以这次我将把我的发现发布出来。

博士TL;大多数人都想使用Exit来终止正在运行的脚本。然而,如果你的脚本只是声明稍后将在shell中使用的函数,那么你将需要在所述函数的定义中使用Return

退出vs返回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
    }
    

抛出一个异常会很好,特别是当你想澄清错误原因时:

throw "Error Message"

这将生成一个终止错误。

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

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

[Environment]::Exit(1)

这将允许您使用特定的退出代码退出,该退出代码可以从调用者那里获得。

我用它来重播一个节目。我不知道它是否有帮助,但它是一个简单的if语句,只需要两个不同的条目。它在powershell中为我工作。

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


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

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

我碰巧发现Break <UnknownLabel>(例如,简单地Break Script标签Script不存在)似乎打破了整个脚本(甚至从一个函数中),并保持宿主存活 通过这种方式,你可以创建一个函数,从任何地方(例如递归循环)中断脚本,而不知道当前范围(并创建标签):

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

当我想让一个函数退出脚本而不抛出错误,但如果从那里使用该函数,则不退出控制台时,我想到了一个简洁的小技巧来做到这一点。它涉及到$PSScriptRoot自动变量,该变量仅在运行脚本时定义。

if($PSScriptRoot){exit}