Как вернуть ненулевой код выхода из функции модуля Powershell, не закрывая консоль powershell? - PullRequest
1 голос
/ 21 ноября 2019

У моего модуля powershell есть функция, и я хочу, чтобы он возвращал ненулевой код завершения. Однако, будучи модульной функцией, она загружается в контекст консоли powershell, когда я запускаю Import-Module. Итак, когда функция выполняет exit 1 - poof, открывается окно консоли!

По крайней мере, я объясняю это закрытием окна powershell при выходе из него.

Итак, как можноВыход из функции модуля ps с ненулевым кодом выхода без уничтожения консоли, куда был импортирован модуль?

PS

Я заметил несколько вопросов на SO по этому вопросу, но ни один из них не рассматривалэтот конкретный случай.

РЕДАКТИРОВАТЬ 1

Я хотел бы предоставить некоторый контекст. У меня есть модуль PS с большим количеством функций. Некоторые из них используются в сценариях сборки yaml Azure DevOps. Последний знает, как распознать ненулевой код выхода и прервать конвейер, поэтому нет необходимости вызывать функцию для прерывания потока.

Однако, если я хочу вызвать эту функцию из консоли, например, длячто-то проверить быстро и завершится с ненулевым кодом, все окно консоли будет закрыто. Это очень раздражает.

Иногда есть обходной путь. Таким образом, вместо этого кода:

dotnet build ...
$ExitCode = $LastExitCode
DoSomethingInAnyCase()
if ($ExitCode)
{
    exit $ExitCode
}

У нас может быть следующая версия:

try
{
    dotnet build ...
}
finally
{
    DoSomethingInAnyCase()
}

Обе версии будут правильно возвращать правильный код выхода, но во второй нетявное выражение exit, оно не закрывает консоль.

1 Ответ

2 голосов
/ 21 ноября 2019

Вам придется установить $global:LASTEXITCODE, чтобы установить код выхода, но учтите, что PowerShell функции на самом деле не предназначены для установки кодов выхода, только сценарии , а последний только для сообщения кодов выхода во внешний мир через собственный код выхода процесса PowerShell, когда PowerShell вызывается через его (CLI powershell.exe для Windows PowerShell, pwsh для PowerShell Core) из инструмента сборки, запланированной задачи или другой оболочки, например.

Также обратите внимание, что установка $global:LASTEXITCODE напрямую:

  • не делает $?, автоматическую переменную состояния успеха, отражающей $false в контексте вызывающей стороны, способ, которым exit <nonzero-value> делает из скрипта, и способ вызова внешней программы, которая сообщает о ненулевом выходекода.

  • недостаточно для того, чтобы процесс PowerShell в целом сообщал этот код завершения.

Короче говоря: Все, что вы получаете, это то, что вызывающая сторона может проверять $LASTEXITCODE после вызова вашей функции, так же, как после вызова external программа .


Обычно коды выхода представляют собой концепцию межпроцессного и не вписываются в мир PowerShell.

Для получения дополнительной информации о кодах выхода в PowerShell см. в этом сообщении .


Для кодов выхода PowerShell аналог $?, автоматическийБулева переменная состояния успеха ($true или $false), которая отражает успех команды PowerShell сразу после этого.
(Если эта команда является вызовом внешней программы, код выхода 0 устанавливает $?на $true, и любой ненулевой устанавливает его на $false).

Оказывается, установив , что было тем, что вы действительно хотели спросить.

Начиная с PowerShell Core 7.0.0-preview.5, вы не можете установить $? напрямую .

На данный момент это единственный способ заставить $? отражать $false в области действия вызывающего абонента, и, наоборот, вы не всегда можете гарантировать, что это $true:

  • Из сценария : Выйдите из сценария с помощью exit <nonzero-integer>

  • Из командлета или функции (также сценария):

    • Выдает ошибку завершения сценария (Throw) или ошибку завершения оператора ($PSCmdlet.ThrowTerminatingError()) - последняя доступна только в advanced функциях и сценариях.

    • Записать ошибку в поток ошибок PowerShell с помощью $PSCmdlet.WriteError() - последний доступен только в расширенных функциях и сценариях.

      • Обратите внимание, что этонеожиданно в настоящее время не применяется к командлету Write-Error - см. этот выпуск GitHub

Примечаниечто обе техники неизменно включают в себя сообщение об ошибке .

Поскольку, похоже, именно этого вы и пытаетесь избежать, вам придется подождать, пока не будет реализована возможность прямой установки $? .

Было принято решение о реализации этой способности , но неясно, когда это будет реализовано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...