为什么“退出”功能在我的 PowerShell 代码中不起作用?

Syd*_*ney 4 powershell

当我尝试“退出”功能时。它不会关闭控制台。它没有任何作用。如何更改它以使其退出控制台?

Write-Host "-------------- MENU ---------------"
Write-Host "Utility Menu"
Write-Host "1 = Help Ipconfig"
Write-Host "2 = Ipconfig"
Write-Host "3 = Notepad"
Write-Host "4 = Calculator"
Write-Host "5 = Exit"
Write-Host "-----------------------------------"

$userinput = Read-Host "Please select a menu item: "

switch ( $userinput )
{
  1 {Help Ipconfig}
  2 {ipconfig}
  3 {start notepad}
  4 {start calc.exe}
  5 {Exit}
}
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 6

现有答案中有有用的信息,但我认为需要概念框架:

exit[...]它不会关闭控制台。

脚本想要终止整个交互式 PowerShell 会话(这将导致控制台窗口关闭)的情况并不常见,并且exit只会在脚本之外执行此操作- 有关详细信息,请参阅底部部分。

如果从脚本或函数[1]中退出整个会话确实是您的意图,请使用,如Colyn1337[Environment]::Exit(0)建议的那样。(是报告进程终止的退出代码,按照惯例,它表示成功;关闭交互式会话时,此退出代码可能无关紧要。)0


背景资料

用于从 PowerShell 退出各种范围的语言关键字

  • break用于退出语句switch循环语句 ( foreach/ for, while, do);也就是说,在这样的语句之后,执行将在相同的范围内继续 - 请参阅概念性的about_Break帮助主题。

    • 陷阱:如果使用breakcontinue 使用封闭循环或switch语句,PowerShell 会在调用堆栈中查找此类语句,并退出它找到的第一个此类语句;如果没有,则终止当前调用堆栈;也就是说,至少封闭的脚本作为一个整体终止。
      • 请注意,管道中的调用ForEach-Object其内置别名是and ,有点令人%困惑foreach)不是循环;要“打破”传递给 的脚本块,即移至下一个管道输入对象,请使用ForEach-Objectreturn
  • return用于退出封闭的脚本文件(如果直接在脚本文件的顶级作用域中执行)或函数脚本块( { ... }),可选地首先通过作为参数传递的表达式或命令输出数据(例如);请参阅概念性about_Return帮助主题。return 'foo'

    • return对脚本报告的退出代码没有影响,因此可能对整个 PowerShell 进程报告的退出代码没有影响;只能用于设置退出代码 - 见下文。exit
  • exit用于退出交互式会话封闭的脚本文件,并可选择设置退出代码

    • 在脚本文件之外,退出整个exit交互式 PowerShell 会话(关闭控制台窗口)。

    • 脚本文件内部,exit始终(仅)退出该脚本 - 即使从该脚本内部的函数调用也是如此。

      • 请注意与 的对比return,它从函数中仅退出该函数,无论是否从脚本内部调用。
    • exit $exitCode- 其中$exitCode代表任何整数[2] - 可用于设置脚本/会话的退出代码;使用justexit与以下相同exit 0

      • 由于 PowerShell 的错误处理 不是cmd.exe基于退出代码(与和等 shell 不同bash),因此设置退出代码主要是为了向外部调用者传达成功与失败的信息

      • 如果您通过 PowerShell 的CLI(例如, )从外部执行脚本pwsh -File script.ps1,则通过设置的退出代码exit $exitCode也将成为进程退出代码,外部调用者(例如 CI 工具)可以检查该退出代码。

        • 在会话内部,由脚本通过设置的退出代码exit $exitCode反映在自动$LASTEXITCODE变量中,但请注意,该变量也可以通过对该程序的进程退出代码的任何调用来设置
      • 有关 PowerShell 中退出代码的相关性和使用的更多信息,请参阅这篇文章。


[1] 正如postanote 的回答所示,exit从已点源(直接加载到)全局范围的函数内部,也会退出整个会话。但是,最好通过明确表示退出整个会话的异常意图。[Environment]::Exit(0)

[2] 从技术上讲,您可以将任何表达式或命令传递给exit(与 一样return,尽管表达式/命令的输出按原样变成那里的数据),但任何至少不能转换为整数的内容 - 例如exit 'not a number'- 都会被悄悄忽略并且 与相同exit 0。另请注意,有效整数的范围平台而异:Windows支持[int]值,即包含负数的有符号 32 位值。相比之下,类 Unix 平台仅支持无符号[byte]值,即从0到 的数字255(负数转换为正数,较大的值仅考虑最低字节)。