.
В PowerShell нет встроенного графического отладчика для построчной проверки сценариев, однако выручают бесплатные и коммерческие инструменты сторонних поставщиков. В таких редакторах, как PowerGUI компании Quest Software (powergui.org), Idera PowerShellPlus (powershellplus.com) и PrimalScript компании SAPIEN Technologies (www.primaltools.com) используют различные методы построчного выполнения сценариев PowerShell, чтобы видеть содержимое переменных и в целом упростить отладку. Однако для успешного применения любого из этих инструментов необходимо овладеть общими навыками отладки.
Прежде чем приступить к отладке, нужно определить объект поиска, иными словами, что считать ошибкой. Существует две отчетливые разновидности ошибок.
Первый тип ошибки: толстые пальцы
Первый тип — простая синтаксическая ошибка. Опечатка. Сбой оператора. Толстые пальцы. Выберите название, которое вам больше нравится. Обнаружить эти ошибки довольно просто, так как PowerShell выдает сообщение, в котором указывается номер строки, содержащей неверный символ. Однако сведения о номере строки мало помогут пользователям Notepad, так как в программе не показаны номера строк. По этой причине рекомендуется заменить Notepad на бесплатную программу PowerGUI или коммерческий редактор сценариев.
Возможности коммерческих редакторов не ограничиваются лишь нумерацией строк, а некоторые их функции помогут предотвратить опечатки. Главная из них — выделение синтаксиса, то есть представление исходного текста сценария различными цветами. Ключевая особенность цветового выделения заключается в том, что элементы окрашиваются в нужный цвет только в случае правильного написания. Поэтому пользователям редакторов с функцией выделения синтаксиса полезно изучить цветовые обозначения команд, переменных, строк литералов и т. д. Если они не окрашиваются нужным цветом во время ввода, значит, произошла ошибка. Остановитесь и выясните причину ошибки.
Если что-то пропущено, от PowerShell поступают сигналы. Обратите внимание на сообщения об ошибках. Очень часто администраторам трудно устранить неполадки просто потому, что они не читают этих сообщений. При виде красного текста на экране они впадают в панику и начинают пробовать разные способы. Но в сообщении указано, в какой строке исходного текста содержится ошибка. Поэтому сосредоточьтесь, внимательно прочитайте сообщение, уясните его смысл и постарайтесь найти причину неполадки.
В хорошем редакторе сценариев можно получить дополнительную информацию, запустив в PowerShell своего рода «предполетную проверку» сценария. Обычно эту функцию называют динамической проверкой синтаксиса. Часто внимание пользователя незамедлительно привлекается к простым ошибкам, еще до запуска сценария. В некоторых редакторах используется красное подчеркивание (как при проверке правописания в Microsoft Word); в других применяются иные визуальные индикаторы.
Наконец, чтобы избежать неприятностей, соблюдайте некоторые правила. Аккуратно структурируйте исходный текст, чтобы конструкции располагались с отступами, выравнивая фигурные скобки, как в следующем примере:
Function get-что-нибудь { # Исходный текст }
Это лучше, чем следующая аморфная запись:
Function get-что-нибудь {# Исходный текст}
Первый пример проще прочитать и проверить наличие открывающих и закрывающих скобок. Во втором случае легко пропустить закрывающую скобку, если используются вложенные конструкции.
Второй тип ошибки: расхождения желаемого и действительного
В результате ошибок второго типа не удается достичь желаемых результатов. Сценарий выполняется без запинок, но не решает поставленную задачу. PowerShell обычно не выдает сообщений об ошибках такого типа или же сообщения не содержат полезной информации. Возможны всего две причины возникновения ошибок подобного типа.
Логическая ошибка. Иногда программисты допускают простые логические ошибки. Например, составлен сценарий, который должен посчитать от 1 до 10:
For ($i=0; $i -lt 10; $i++) { Write-host $i }
Сценарий выполняется успешно, но отображаются числа от 0 до 9. Результат близок, но не совсем соответствует намерениям программиста. В этом случае полезно остановиться и вспомнить принципы выполнения сценариев. Представьте, как программа PowerShell прочитывает сценарий, отметьте содержимое переменных на каждом шаге и результаты каждого шага. Для приведенного сценария ход рассуждений может быть следующим.
Сначала нужно назначить переменной $i значение 0 (записываем $i=0). 0 меньше 10? Да, поэтому используем Write-Host для отображения значения 0 (записывается результат 0) и увеличиваем значение переменной $i на единицу. На данном этапе $i содержит 1 (записываем $i=1). 1 меньше 10? Да, поэтому отображается значение 1 (записывается результат 0) и переменная $i увеличивается на единицу. Теперь $i содержит 2 (записываем $i=2). Это число меньше 10, поэтому оно выводится на экран (записывается результат 2) и т. д.
Так будет продолжаться, пока значение $i не достигнет 10. В результате сравнения оказывается, что 10 не меньше 10, поэтому PowerShell не отображает это число. Как показано в примере, элементарные логические ошибки становятся очевидными, если уделить время простому анализу алгоритма.
Неверные предположения. Поэтапное воспроизведение алгоритма поможет найти не только элементарные, но и более серьезные логические ошибки, так как запись на бумаге содержит перечень ожидаемых состояний. Предположим, программист мысленно воспроизвел сценарий и записал события, которые, по его мнению, должны произойти. В ходе выполнения сценария происходит нечто другое. Такую ошибку можно назвать «ложными ожиданиями» или «незнанием». Причина проста: значение переменной, свойства или результат метода иные, чем предполагалось. В результате анализа логики сценария был составлен письменный перечень ожидаемых состояний. Нужно лишь составить аналогичный список с помощью PowerShell и посмотреть, какие результаты отличаются от ожидаемых. Обнаружив различия, вы найдете ошибку.
Существует два основных метода формирования в PowerShell списка, соответствующего создаваемому в процессе мысленной проверки алгоритма. Эти методы основаны на использовании команд Write-Debug и Set-PSDebug. Существует и третий способ с использованием интерактивного отладчика в редакторе сценариев. В сущности, этот метод представляет собой комбинацию двух базовых методов, которые будут рассмотрены в данной статье. Полезно освоить базовые приемы, прежде чем воспользоваться более удобным способом интерактивного отладчика в редакторе.
Метод 1: Write-Debug
В первом методе используется команда Write-Debug. По умолчанию вывод этой команды подавляется. Чтобы разрешить вывод, необходимо добавить в начало сценария строку
$DebugPreference = "Continue"
Затем следует ввести инструкции Write-Debug непосредственно после каждой инструкции, в которой изменяется содержимое переменной, например:
$var = get-service Write-Debug "`$var contains $var"
Обратите внимание на небольшую хитрость: вывод команды Write-Debug заключен в двойные кавычки. В результате переменные заменяются их содержимым. Для первой переменной используется обратный апостроф (экранирующий символ в PowerShell), поэтому символ $ экранирован. Это приводит к тому, что первый элемент $var отображается как есть, а имя переменной выводится на экран. Второй элемент $var заменяется его содержимым.
Затем нужно ввести инструкцию Write-Debug в каждый цикл и конструкцию принятия решения. В листинге показано, как применить метод для цикла for и конструкции if. В инструкции Write-Debug во фрагменте A используется тот же прием с двойными кавычками и обратным апострофом, чтобы выяснить содержимое $i при каждом повторении цикла for. В конструкции if используются две функции Write-Debug, в том числе и в конструкции else (фрагмент B). Таким образом удается собрать данные для диагностики независимо от ветвления, несмотря на отсутствие программного кода, который бы исполнялся, когда значение $i не больше 2. Обратите внимание, что для вывода инструкций Write-Debug используется одинарная кавычка, чтобы не заменять переменную $i ее содержимым.
Листинг. Добавление Write-Debug к инструкциям for и if |
После добавления всех инструкций Write-Debug нужно запустить сценарий и сравнить вывод с записанными ожидаемыми значениями. Отметьте любые различия. Возможно, придется пересмотреть ожидания, но любое различие следует рассматривать как указатель на потенциальную ошибку.
Если сценарий выполняется, как ожидалось, просто замените $DebugPreference в начале сценария на
$DebugPreference = "SilentlyContinue"
и диагностический вывод будет подавлен. Удалять инструкции Write-Debug не обязательно. Оставив их на месте, можно облегчить отладку сценария в будущем.
Метод 2: Set-PSDebug
Второй метод основан на использовании встроенного пошагового отладчика Set-PSDebug для построчного выполнения сценария. В длинных сценариях процедура может показаться утомительной, но в PowerShell 1.0 приходится довольствоваться этим. В PowerShell 2.0 появились контрольные точки, о которых будет рассказано в следующей статье. С их помощью можно задать момент перехода сценария в режим ожидания, не выполняя его построчно.
Для запуска отладчика выполните команду
set-PsDebug -step
Позднее его можно отключить командой
set-PsDebug -off
Включенный отладчик действует на все сценарии (а также на команды, введенные в командной строке). Нужно просто запустить сценарий и приступить к отладке. Каждый раз, обнаруживая строку сценария, PowerShell отображает ее и просит подтверждения, чтобы продолжить выполнение. Полезно иметь распечатку с пронумерованными строками, чтобы точно видеть, какое место сценария выполняет PowerShell. Чтобы выполнить строку, нажмите клавишу Enter. В процессе выполнения можно сравнивать ожидаемые результаты с реально полученными.
Не нажимайте клавишу Enter всякий раз, когда сценарий изменяет переменную или готовится обратиться к свойству переменной или объекта. Вместо этого введите S и нажмите Enter. При этом выполнение сценария приостанавливается, и на экране появляется особое приглашение. С его помощью можно:
- обращаться к переменным, чтобы увидеть их содержимое;
- запускать команды, чтобы увидеть их результат;
- просматривать свойства объекта, чтобы увидеть их содержимое.
Различие между реальными и ожидаемыми результатами свидетельствует об ошибке. Выполните команду Exit, чтобы выйти из режима ожидания и возобновить выполнение сценария с того места, где он был остановлен.
Требуется некоторое время, чтобы привыкнуть к пошаговому отладчику. Однако это полезный инструмент для проникновения внутрь выполняемого сценария.
К отладке готов?
Процедура отладки не обязательно сложна при методичном и согласованном подходе. Не расстраивайтесь, получая сообщение об ошибке. Внимательно прочитайте и уясните смысл сообщения. Отнеситесь к нему как к полезной (хотя и непрошеной) подсказке.
Если результаты не соответствуют ожидаемым, документируйте свои предположения и выясните, почему они не соответствуют действительности. Основная причина ошибок в том, что программист не знает, чего ожидать на каждом шаге выполнения сценария. Это типично для начинающих администраторов, которые пытаются, например, использовать сценарии, заимствованные из Интернета. Уделив время изучению сценария, вы не только ускорите отладку, но и больше узнаете о PowerShell и сможете успешно создавать собственные сценарии в будущем, а умение выполнять отладку всегда пригодится в работе.
Дон Джоунз (powershell@concentratedtech.com) — инструктор по PowerShell (www.windowsitpro.com/go/DonJonesPowerShell), имеет звание MVP; автор более 35 книг, выступает на таких технологических конференциях, как Microsoft TechEd и Windows Connections