Завершение сценария в PowerShell



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



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


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



Edit: Да, это просто exit. Да.

771   10  

10 ответов:

вы должны использовать the exit ключевое слово.

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

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

выход против возврата против перерыва

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

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

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

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

    выполнение любых команд после точки вызова, в которую она возвращается, будет продолжено с этой точки. Если скрипт вызывается из оболочки и содержит Return команда вне любых функций, то когда он возвращается к в оболочке больше нет команд для запуска, что делает 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
    }
    

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..."
}

Write-Error - это для непрекращающихся ошибок и бросить предназначен для завершения ошибок

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

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

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

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

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

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

[Environment]::Exit(1)

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

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

throw "Error Message"

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

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

Get-Help about_trap

чтобы узнать больше о инструкции trap.

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

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

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

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

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

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

Comments

    Ничего не найдено.