Завершение script в PowerShell

Я искал способ прервать PowerShell (PS1) script, когда в функции возникает неустранимая ошибка. Например:

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

Конечно, нет такой вещи, как $host.Exit(). Существует $host.SetShouldExit(), но это фактически закрывает окно консоли, чего я не хочу. Мне нужно что-то эквивалентное Python sys.exit(), которое просто прекратит выполнение текущего script без дальнейшего прощания.

Изменить: Да, это просто exit. Duh.

Ответ 2

Я понимаю, что это старый пост, но я снова возвращаюсь к этой теме, так как это один из лучших результатов поиска при поиске этой темы. Тем не менее, я всегда оставляю больше смущения, когда я пришел из-за противоречивой информации. В конечном счете, я всегда должен выполнить свои собственные тесты, чтобы понять это. Поэтому на этот раз я опубликую свои выводы.

TL; DR. Большинство людей захотят использовать Exit для прекращения запуска сценариев. Однако, если ваш script просто объявляет функции, которые позднее будут использоваться в оболочке, тогда вы захотите использовать Return в определениях указанных функций.

Выход vs Возврат vs Разрыв

  • Выход: Это приведет к "выходу" из текущего контекста. Если вы вызываете эту команду из script, она выйдет из script. Если вы вызовете эту команду из оболочки, она выйдет из оболочки.

    Если функция вызывает команду "Выход", она выйдет из контекста, в котором он запущен. Поэтому, если эта функция вызывается только из запущенного script, она выйдет из этого script. Однако, если ваш script просто объявляет функцию так, чтобы ее можно было использовать из текущей оболочки, и вы запустили эту функцию из оболочки, она выйдет из оболочки, потому что оболочка - это контекст, в котором функция, связанная с Exit команда запущена.

    Примечание.. По умолчанию, если вы щелкните правой кнопкой мыши по script, чтобы запустить его в PowerShell, как только script будет запущен, PowerShell закроется автоматически. Это не имеет ничего общего с командой Exit или чем-либо еще в вашем script. Это просто поведение PowerShell по умолчанию для запуска скриптов с использованием этого конкретного метода запуска script. То же самое можно сказать о командных файлах и окне командной строки.

  • Возврат:. Это вернется к предыдущей точке вызова. Если вы вызовете эту команду из script (вне любых функций), она вернется в оболочку. Если вы вызовете эту команду из оболочки, она вернется в оболочку (которая является предыдущей точкой вызова для одной команды, запущенной из оболочки). Если вы вызовете эту команду из функции, она вернется туда, откуда была вызвана функция.

    Выполнение любых команд после того, как точка вызова, на которую он возвращается, будет продолжена с этой точки. Если из оболочки вызывается script, и она содержит команду Return вне любых функций, тогда, когда она возвращается в оболочку, больше нет команд для запуска, что делает используемым таким образом Return по существу таким же, как Exit.

  • Разрыв: Это вырвется из циклов и корпусов переключателей. Если вы вызовете эту команду, когда она не находится в цикле или корпусе коммутатора, он вырвется из script. Если вы вызовете 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
    }
    

Ответ 3

Exit также выйдет из PowerShell. Если вы хотите "сломать" только текущую функцию или script - используйте 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..."
}

Ответ 4

Ошибка записи - для ошибок, не заканчивающихся и throw - для завершения ошибок

Командлет Write-Error объявляет необратимую ошибку. По умолчанию, ошибки отправляются в поток ошибок в хост-программу, чтобы отображается вместе с выходом.

Неограничивающие ошибки записывают ошибку в поток ошибок, но они не останавливают обработку команд. Если недопустимая ошибка объявленный по одному элементу в коллекции входных элементов, команда продолжает обрабатывать другие предметы в коллекции.

Объявить завершающая ошибка, используйте ключевое слово Throw. Для получения дополнительной информации см. about_Throw (http://go.microsoft.com/fwlink/?LinkID=145153).

Ответ 5

Завершает этот процесс и предоставляет базовой операционной системе указанный код выхода.

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

[Environment]::Exit(1)

Это позволит вам выйти с определенным кодом выхода, который может быть выбран из вызывающего.

Ответ 6

Я думаю, что вы ищете Return вместо Break. Разрыв обычно используется для циклов и только перерывы из самого внутреннего блока кода. Используйте Return для выхода из функции или script.

Ответ 7

Бросок исключения будет хорошим, особенно если вы хотите уточнить причину ошибки:

throw "Error Message"

Это приведет к завершающей ошибке.

Ответ 8

Может быть, лучше использовать "ловушку". Ловушка PowerShell определяет код для запуска при завершении или ошибке. Тип

Get-Help about_trap

чтобы узнать больше о заявлении trap.

Ответ 9

Я случайно обнаружил, что Break <UnknownLabel> (например, просто Break Script, где метка Script не существует), как представляется, вырывается из всего script (даже изнутри функции) и удерживает хост жив.
Таким образом, вы можете создать функцию, которая разбивает script из любого места (например, рекурсивный цикл), не зная текущей области (и создания меток):

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

Ответ 10

Я использовал это для повторной программы. Я не знаю, поможет ли это, но это простой оператор if, требующий только двух разных записей. Это работало для меня в powershell.

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

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

Не знаю, помогает ли это, но я полагаю, что это будет по очереди завершать программу после ее запуска. Однако в этом случае для каждого определенного входа требуется список и категоризированный вывод. Вы также можете вызвать вызов новой строки приглашения и таким образом завершить программу.

Ответ 11

Я использую:

throw "something bad happened"