【问题标题】:PowerShell exit() kills shell and ISEPowerShell exit() 杀死 shell 和 ISE
【发布时间】:2016-08-15 13:34:37
【问题描述】:

所以我编写了一系列函数并将它们插入到 PS 模块 (.psm1) 中。其中之一是一个简单的 ErrorAndExit 函数,它向 STDERR 写入一条消息,然后调用 exit(1);,这是一种允许轻松重定向错误消息的习惯。在正常的 PowerShell 或 ISE 中调试我的脚本时,如果我调用一个又调用 ErrorAndExit 的函数,它不仅会退出脚本,还会退出整个 PowerShell 进程。终端和 ISE 都会立即死亡。终端,我可能只是理解,但是 ISE?!当然,最令人沮丧的部分是在窗口消失之前我看不到错误消息。

我相信这与我的调试方式有关 - 我已经定义了很多发生在链中的函数,并注释掉了启动链的调用。我正在导入脚本并从提示符调用函数。由于脚本是为自动化设计的,所以在实际使用中杀死整个PS进程不会有问题,但我需要看看调试输出是什么。

有问题的函数,在 Common.psm1 中:

function errorAndExit([string]$message)
{
    logError($message);
    exit(1);
}

其中logError$message 传递给Write-Error。此调用导致 PS 或 ISE 终止的示例函数:

function branch([string]$branchName, [int]$revision, [string]$jenkinsURL, [switch]$incrementTrunk)
{
    Set-Variable -Name ErrorActionPreference -Value Stop;
    log("Script starting, parameters branchName=$branchName, revision=$revision, jenkinsURL=$jenkinsURL");
    if (-not ($branchName -match "\d{4}\.\d{2}\.\d"))
    {
        errorAndExit("Provided branch name $branchName is not a valid YYYY.MM.R string");
    }
...

我的 Common.psm1 模块正在使用简单的Import-Module -Force "$PSScriptRoot\Common"; 导入。从 PS 提示符调用时:

PS C:\Windows\system32> branch -branchName abc

导致 PowerShell 或 ISE 完全退出。

我是从 Bash 的心态开始使用 PowerShell 的,并且已经编写了这样的脚本(但是习惯于传递对象),但这不是我期望从任何脚本语言中获得的行为。

【问题讨论】:

  • 不要使用exit,如果您希望脚本在出错时停止,请设置$ErrorActionPreference = 'Stop'
  • @MathiasR.Jessen 是的,我已经这样做了,请参阅代码 sn-p。这是关于首先提出错误。
  • @Gargravarr - 我们不使用括号 - ( ) - 在 PowerShell 中执行函数。这在语法上是有效的,但在语义上是错误的。 logError($message) 应该是logError $messageexit(1) 应该是exit 1,等等

标签: powershell exit powershell-ise


【解决方案1】:

在 Powershell ISE 中,exit 命令会关闭整个 IDE,而不仅仅是当前的命令选项卡。

https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/13223112-would-be-better-if-the-exit-command-in-powershell

您对exit 的使用在您的errorAndExit 函数中有一点缺陷。如前所述,throwreturn $false 并评估结果将是更好的选择。

【讨论】:

  • 感谢您的建议。投掷是我需要的;调用 exit() 是我通常在其他语言中执行此操作的方式,我确信我希望脚本由于数据错误而立即停止。我仍然对让 exit() 杀死整个 PowerShell.exe 进程的决定感到困惑,即使在脚本中也是如此。
  • 是的,Powershell 的函数实现有点古怪。我一直认为return 但实际上一个函数所做的只是添加到管道中,因此您必须小心不要使用其他命令行开关添加到管道中。 Throw 有效,但前提是您的陷阱到位。
  • Alternatively Write-Error 提供了更多用于生成错误的选项,并且更适合 PowerShell 语言。
【解决方案2】:

我不知道为什么你不能只throw 你的错误信息。如果您必须使用来自exit 的返回码,但不想在 ISE 中这样做,请考虑更改您的函数:

function errorAndExit([string]$message)
{
    logError $message
    if ($Host.Name -eq 'Windows PowerShell ISE Host') {
        throw $message
    } else {
        exit 1
    }
}

【讨论】:

  • 感谢您的建议,您是对的,我没有使用正确的流程。我仍然觉得奇怪的是 exit() 隐式地杀死了整个 PowerShell.exe 进程。
【解决方案3】:

尝试Throw 关键字,它用于引发您以后可以在try-catch 块中使用的异常。

【讨论】:

  • 感谢您的建议,看起来正是我所需要的
猜你喜欢
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 1970-01-01
  • 2020-11-30
  • 2016-07-08
  • 2014-02-06
相关资源
最近更新 更多