Ответ 1
Вы должны использовать ключевое слово exit
.
Я искал способ прервать PowerShell (PS1) script, когда в функции возникает неустранимая ошибка. Например:
function foo() {
# Do stuff that causes an error
$host.Exit()
}
Конечно, нет такой вещи, как $host.Exit()
. Существует $host.SetShouldExit()
, но это фактически закрывает окно консоли, чего я не хочу. Мне нужно что-то эквивалентное Python sys.exit()
, которое просто прекратит выполнение текущего script без дальнейшего прощания.
Изменить: Да, это просто exit
. Duh.
Вы должны использовать ключевое слово exit
.
Я понимаю, что это старый пост, но я снова возвращаюсь к этой теме, так как это один из лучших результатов поиска при поиске этой темы. Тем не менее, я всегда оставляю больше смущения, когда я пришел из-за противоречивой информации. В конечном счете, я всегда должен выполнить свои собственные тесты, чтобы понять это. Поэтому на этот раз я опубликую свои выводы.
TL; DR. Большинство людей захотят использовать Exit
для прекращения запуска сценариев. Однако, если ваш script просто объявляет функции, которые позднее будут использоваться в оболочке, тогда вы захотите использовать Return
в определениях указанных функций.
Выход: Это приведет к "выходу" из текущего контекста. Если вы вызываете эту команду из 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
}
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..."
}
Ошибка записи - для ошибок, не заканчивающихся и throw - для завершения ошибок
Командлет Write-Error объявляет необратимую ошибку. По умолчанию, ошибки отправляются в поток ошибок в хост-программу, чтобы отображается вместе с выходом.
Неограничивающие ошибки записывают ошибку в поток ошибок, но они не останавливают обработку команд. Если недопустимая ошибка объявленный по одному элементу в коллекции входных элементов, команда продолжает обрабатывать другие предметы в коллекции.
Объявить завершающая ошибка, используйте ключевое слово Throw. Для получения дополнительной информации см. about_Throw (http://go.microsoft.com/fwlink/?LinkID=145153).
Завершает этот процесс и предоставляет базовой операционной системе указанный код выхода.
https://msdn.microsoft.com/en-us/library/system.environment.exit%28v=vs.110%29.aspx
[Environment]::Exit(1)
Это позволит вам выйти с определенным кодом выхода, который может быть выбран из вызывающего.
Я думаю, что вы ищете Return
вместо Break
. Разрыв обычно используется для циклов и только перерывы из самого внутреннего блока кода. Используйте Return для выхода из функции или script.
Бросок исключения будет хорошим, особенно если вы хотите уточнить причину ошибки:
throw "Error Message"
Это приведет к завершающей ошибке.
Может быть, лучше использовать "ловушку". Ловушка PowerShell определяет код для запуска при завершении или ошибке. Тип
Get-Help about_trap
чтобы узнать больше о заявлении trap.
Я случайно обнаружил, что Break <UnknownLabel>
(например, просто Break Script
, где метка Script
не существует), как представляется, вырывается из всего script (даже изнутри функции) и удерживает хост жив.
Таким образом, вы можете создать функцию, которая разбивает script из любого места (например, рекурсивный цикл), не зная текущей области (и создания меток):
Function Quit($Text) {
Write-Host "Quiting because: " $Text
Break Script
}
Я использовал это для повторной программы. Я не знаю, поможет ли это, но это простой оператор if, требующий только двух разных записей. Это работало для меня в powershell.
$rerun = Read-Host "Rerun report (y/n)?"
if($rerun -eq "y") { Show-MemoryReport }
if($rerun -eq "n") { Exit }
Не знаю, помогает ли это, но я полагаю, что это будет по очереди завершать программу после ее запуска. Однако в этом случае для каждого определенного входа требуется список и категоризированный вывод. Вы также можете вызвать вызов новой строки приглашения и таким образом завершить программу.
Я использую:
throw "something bad happened"