Сегодня подходим к самому интересному. Ключевое слово trap позволяет ставить «ловушки» для ошибок, и таким образом становится возможным реагировать даже на неожиданные ошибки. Но сначала рассмотрим базовую конструкцию:
[PS <105> C:\Root] trap { Write-Warning "Ошибка!" }; copy test.ps1 \\сервер\шара
WARNING: Ошибка!
Copy-Item : Не найдено сетевое имя.
At line:1 char:39
+ trap { Write-Warning "Ошибка!" }; copy <<<< test.ps1 \\сервер\шара
Здесь после ключевого слова идет скриптблок (подпрограмма), внутри которого вызывается командлет Write-Warning. Этот скриптблок и был вызван при возникновении ошибки, подарив нам красивую желтую надпись «WARNING: Ошибка! «. Разумеется там можно написать и более осмысленный и полезный код
Кроме того внутри этого скриптблока, в качестве последней выполняемой команды можно поместить ключевые слова continue или break. Соответственно в первом случае будет выполнен скриптблок, и выполнение скрипта будет возобновлено, а во втором – работа будет прервана:
[PS <106> C:\Root] trap { Write-Warning "Ошибка!"; Continue }; copy test.ps1 \\сервер\шара
WARNING: Ошибка!
Я не просто так поместил trap и команду вызывающую ошибку в одной строке. Дело в том что область действия trap ограничивается текущим скриптблоком и всеми вложенными. То есть так trap вызван не будет:
[PS <107> C:\Root] trap {write-warning "Ошибка!"}
[PS <108> C:\Root] copy test.ps1 \\сервер\шара
Copy-Item : Не найдено сетевое имя.
At line:1 char:5
+ copy <<<< test.ps1 \\сервер\шара
А если поместить в один скриптблок – сработает:
[PS <109> C:\Root] & {
>> trap {Write-Warning "Ошибка в скриптблоке"; Continue}
>> copy test.ps1 \\сервер\шара
>> }
>>
WARNING: Ошибка в скриптблоке
Аналогично прекрасно отработает в пределах функции:
[PS <110> C:\Root] function Test-Error {
>> trap {Write-Warning "Ошибка в функции"; Continue}
>> copy test.ps1 \\сервер\шара
>> }
>>
[PS <111> C:\Root] Test-Error
WARNING: Ошибка в функции
Ну и разумеется если поместить блок trap внутри файла .ps1 он будет ловить ошибки во всём коде внутри этого файла, и во всех вложенных в него функциях.
Продолжение следует…









Хочу добавить маленькое замечание по поводу trap. Всё работает в пределах данного примера. Но если исходный файл отсутствует (в нашем случае test.ps1), то trap не сработает. Или копирование файла в пределах лоакльной машины (не на сетевой путь, а на локальный, например D: ). Если я что-то упустил из последних сообщений, то не пинать больно ногами
Комментарий от Camelot — 15.4.2008 @ 16:02
Дело в том что тут у тебя возникает «не останавливающая выполнение» ошибка. Действительно – было бы неправильно если бы ты скормил copy-item 20 путей, и он прервал бы выполнение из за того что 4й путь неправильный. Я об этом постараюсь рассказать еще позже, а пока просто добавляй к copy ключ -ea 1 или установи $ErrorActionPreference = «Stop».
Комментарий от Xaegr — 15.4.2008 @ 19:32
на PowerShell.
http://groups.google.com/group/ru-powershell/msg/f54369bbcc1cd8b4
Комментарий от ajax76 — 16.4.2008 @ 3:13
[...] команды прерывается (по умолчанию), и если установлен trap, то выполняется определённый в нём [...]
Уведомление от Не все $Errors одинаково критичны « PowerShell и другие скрипты — 18.4.2008 @ 8:17
Возник вопросец, а как избежать вывода ошибок, если используется gwmi, но пользователь под учетной записью которого производится подключение не имеет прав на доступ к удаленному компьютеру?
Комментарий от Evgeny — 6.10.2008 @ 10:50