我一直在寻找一种在函数中发生不可恢复的错误时终止PowerShell(PS1)脚本的方法。例如:
function foo() {
# Do stuff that causes an error
$host.Exit()
}
当然没有$host.Exit()
之类的东西。有$host.SetShouldExit()
,但这实际上关闭了控制台窗口,这不是我想要的。我需要的是与Python的sys.exit()
相当的东西,只需停止执行当前脚本而不需要进一步执行。
编辑:是的,它只是exit
。咄。
答案 0 :(得分:517)
我意识到这是一篇很老的帖子,但我发现自己回到这个帖子很多,因为它是搜索这个主题时的顶级搜索结果之一。但是,当我来到时,由于信息冲突,我总是更加困惑。最终,我总是要进行自己的测试来弄明白。所以这次我会发布我的发现。
TL; DR 大多数人都希望使用Exit
来终止正在运行的脚本。但是,如果您的脚本只是声明稍后在shell中使用的函数,那么您将需要在所述函数的定义中使用Return
。
退出:这将"退出"当前运行的上下文。如果从脚本调用此命令,它将退出脚本。如果从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 }
不知道这是否有帮助,但我相信这会在您运行程序后终止程序。但是,在这种情况下,每个定义的输入都需要列出和分类的输出。你也可以让退出调用一个新的提示行并以这种方式终止程序。