Обробка помилок в PowerShell (частина 1).
Для початку визначимося, що таке обробка помилок взагалі. У загальному випадку помилка - це поведінка програми або скрипта, відмінне від запланованого. Зовсім уникнути помилок не дуже можливо, тому треба передбачити, де вони можуть виникнути і писати код так, щоб при виникненні помилки можна було перехопити її, проаналізувати і визначити подальшу поведінку скрипта.Саме це зазвичай і мається на увазі під обробкою помилок.
В PowerShell помилки діляться на два типи: переривають (Terminating) і неперервні (Non-Terminating). Як випливає з назви, неперервні помилки дозволяють продовжити виконання команди, тоді як при виникненні перериває помилки подальше продовження виконання команди неможливо.Наприклад, у нас є файл зі списком служб, які необхідно перезапустити наступною командою:
Get-Content -Path C: \ Files \ services.txt | Restart-Service
Припустимо, що перезапуск однієї з перерахованих служб по якійсь причині неможливий. Проте можна продовжувати виконання завдання, оскільки інші служби доступні і їх можна запустити знову.Це приклад неперервні помилки.
А тепер уявіть, що у нас немає прав на відкриття цього файлу, і відповідно прочитати список служб ми не можемо. У цій ситуації продовження роботи неможливо, тобто це перериває помилка.
PowerShell дозволяє обробляти обидва ці типи помилок.Більшість помилок в PowerShell неперервні, і сьогодні мова піде про те, як їх обробляти.
Обробка неперервні помилок
Для отримання помилки візьмемо службу з "оригінальним" назвою Service. Оскільки служби цієї на сервері немає, то звернення до неї стабільно буде генерувати помилку.Запитаємо дані про декілька службах командою:
Get-Service service, spooler
Як видно з прикладу, PowerShell не знайшов службу Service, про що видав помилку і потім продовжив виконання команди. Давайте розберемося, чому команда повела себе саме так і як це поведінка змінити.
За поведінку команди при виникненні помилки відповідає параметр ErrorAction, який може приймати одне з п'яти значень:
• Continue;
• SilentlyContinue;
• Stop;
• Ignore;
• Inquire.
Примітка. Ще у ErrorAction може бути значення Suspend. Але це значення може застосовуватися тільки до робочих процесів (workflows), тому в рамках даної статті мова про нього не піде.
Значення Continue означає, що при виникненні помилки інформація про це буде виведена на екран (відправлена в потік виведення Error) і додана в автоматичну змінну $ Error, після чого виконання команди буде продовжено.Треба сказати, що Continue - це дія, яка визначена сеансі за замовчуванням, тому його можна не вказувати явно.
При значенні SilentlyContinue інформація про помилку додається в змінну $ Error, але не виводиться на екран. При цьому команда залишиться активним далі, також як і в попередньому випадку.
Значення Stop зупиняє подальше виконання команди при виникненні помилки. І навпаки, значення Ignore повністю ігнорує виникнення помилки, при цьому не виводиться повідомлення на екран і не проводиться запис в $ Error. Це значення з'явилося в PowerShell 3.0.
Inquire - найцікавіша значення ErrorAction. Якщо задати це значення, то при виникненні помилки пропонується на вибір кілька дій: продовжити (Yes), продовжити не дивлячись на цю і всі наступні помилки (Yes to All), зупинити (Halt) або призупинити (Suspend) виконання команди.
Найбільш незвичайний ефект дає Suspend, при виборі якого відкривається паралельний сеанс (Nested Namespace). Визначити його можна по значку >>. Nested Namespace вдає із себе дочірній процес, в якому можна повноцінно працювати - виконувати команди, запускати скрипти і т.п. Цей режим зручно використовувати для налагодження скриптів, наприклад можна по швидкому виправити причину помилки і продовжити виконання.Для виходу з Nested Namespace досить набрати exit і вибрати необхідну дію.
Примітка. У параметра ErrorAction є алиас - EA. Крім того, замість назви параметра можна вказувати числові значення: 0 (SilentlyContinue), 1 (Stop), 2 (Continue), 3 (Inquire). Так наприклад, замість:
Get-Service service, spooler -ErrorAction SilentlyContinue
можна написати так:
Get-Service service, spooler -EA 0
Змінні для обробки помилок
Як я вже говорив, якщо не вказувати параметр ErrorAction, то для команди діє режим обробки помилок, визначений в сеансі.Цей режим задається змінною $ ErrorActionPreference, яка за замовчуванням має значення Continue. При бажанні можна перевизначити режим для всього сеансу, задавши змінної $ ErrorActionPreference потрібне значення.
Все помилки PowerShell зберігає в автоматичну змінну $ Error. Це глобальна змінна, яка вдає із себе масив рядків, що містить записи про всі помилки в поточному сеансі.Кожна нова помилка додається в початок масиву, відповідно для перегляду останньої помилки треба звернутися до найпершого елементу масиву $ Error [0].
$ Error має свої властивості і методи, які можна використовувати. Наприклад, подивитися загальна кількість помилок в поточному сеансі можна командою $ Error.Count, а очистити список - командою $ Error.Clear ().
Змінна $ Error НЕ безрозмірна, за замовчуванням вона зберігає не більше 256 помилок. При перевищенні цієї кількості найбільш старі помилки будуть затирається. При необхідності кількість записів в змінній $ Error можна збільшити, змінивши значення іншої змінної $ MaximumErrorCount.
Крім $ Error для зберігання помилок допускається задавати власні змінні. Зробити це можна за допомогою параметра ErrorVariable, наприклад так:
Get-Service service, spooler -ErrorAction SilentlyContinue -ErrorVariable var
Зверніть увагу, що ім'я змінної в команді задається без знака $, хоча в подальшому до неї звертаємося як до звичайної змінної $ var.
На відміну від глобальної змінної $ Error задані вручну змінні зберігають тільки помилки тієї команди, в якій вони визначені. Крім того, за замовчуванням ці змінні кожен раз перезаписувати і тому зберігають тільки останню помилку. Якщо ви хочете, щоб нові помилки додавалися в змінну, що не переписуючи її вміст, то перед ім'ям змінної треба поставити знак +, наприклад + var.
Поки все, а в наступній частині піде про способи обробки переривають помилок.
.