Вопрос или проблема
Я столкнулся с чем-то в PowerShell, и не знаю, делаю ли я что-то неправильно или это просто баг в PowerShell (и я не могу найти ответ нигде)? Я тестировал это на версиях PowerShell 4, 5.0 и 5.1, используя разные версии Windows. Сначала кажется, что неважно, какая версия ОС и какая версия PowerShell, когда я запускаю следующий код либо напрямую в окне PowerShell, либо через скрипт PowerShell, я не получаю ошибок, и все кажется в порядке:
$error.clear()
If ($error -ne $null) { $error }
Однако на некоторых типах систем (по-видимому, это проблема, связанная с ОС) я запускаю следующий код и иногда получаю ошибку:
$error.clear()
If ($error -ne $null)
{
$error
}
Я могу запустить вышеуказанный код, генерирующий ошибку, на Windows 10 и серверах Windows 2016, и все в порядке (ошибки не сообщаются). Если я запускаю точно такой же код на Windows 2008 R2 или Windows 2012 R2, я получаю следующее сообщение об ошибке:
Отсутствует блок операторов после If (условие).
Не имеет значения, установлена ли у меня PowerShell 4, 5 или 5.1.1 на системах Windows 2008 R2 и Windows 2012 R2, я все равно получаю ошибку. И неважно, запускаю ли я от имени администратора или нет, результаты одинаковы. И это не кажется имеющим значение, являются ли они присоединенными к домену или системами рабочей группы. Все наши системы обновлены по состоянию на обновления во вторник патчей в мае 2017 года.
Является ли требованием PowerShell (на системах Windows 2008 R2 и Windows 2012 R2), чтобы открывающая фигурная скобка оператора “IF” находилась на той же строке, что и сам оператор IF? Для Windows 10 и сервера Windows 2016, похоже, это не так.
Заранее спасибо,
UCG
Когда PowerShell получает строку (или блок) кода – он оценивает этот блок (или строку) как единое целое.
В этом случае ваша первая строка: If ($error -ne $null)
PowerShell знает, как интерпретировать строку, но это неверный синтаксис, потому что в PowerShell нет блока “что делать” на случай, если критерии выполнены.
Если вы передадите PowerShell блок целиком – он распознает “блок, что делать” и знает, куда ему нужно идти дальше:
Можете ли вы подробнее рассказать о том, какие системы и платформы вы находите, которые принимают отдельные строки? Я только что протестировал это на Win10 (PowerShell 5), 2012R2 (PowerShell 4 и 5), Windows 7 (PowerShell 4 и 5), и они все ведут себя совершенно одинаково.
У меня была такая же проблема, когда мой блок операторов включал строку явно.
If ($error -ne $null)
{
$query = @"
выполняем sql;
делаем еще sql;
"@
}
Когда я изменил это на одну строку без явно, это сработало.
If ($error -ne $null)
{
$query = "выполняем sql; делаем еще sql;"
}
В вашем блоке операторов может быть что-то, что PowerShell не позволяет использовать в многострочных форматах.
PowerShell имеет два способа разбора команд: режим выражений и режим аргументов. (см. https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing?view=powershell-7.1)
Не имея разных операционных систем для тестирования, я могу предположить, что эти команды изменились с режима выражений на режим аргументов (или наоборот, в зависимости от того, в какую сторону вы идете) между вашими ОС.
Самый простой обходной путь (лучшая практика) – всегда оставлять открывающую фигурную скобку на верхней строке. Это позволяет команде/скрипту работать независимо от того, какой режим использует парсер.
Вы также можете заставить строку продолжаться, добавив обратную кавычку ` в конец строки. Однако они плохо видимы и могут вызвать другие проблемы, так что ваш опыт может отличаться.
Ответ или решение
Проблема с фигурными скобками в инструкциях IF на PowerShell
Введение
PowerShell – это мощный инструмент автоматизации и управления, который используется администраторами систем и разработчиками по всему миру. Однако, как и с любым языком программирования, в PowerShell могут возникать некоторые сложности и неопределенности, особенно когда дело касается синтаксиса. Эта статья будет посвящена проблеме, связанной с фигурными скобками в инструкциях IF, которая наблюдается на разных версиях операционных систем.
Описание проблемы
Ваша проблема связана с использованием фигурных скобок после инструкции IF и тем, как PowerShell интерпретирует разделение строк. На системах Windows 2008 R2 и 2012 R2 вы сталкиваетесь с ошибкой «Отсутствует блок операторов после IF (условие)» при использовании следующего кода:
$error.clear()
If ($error -ne $null)
{
$error
}
На платформах Windows 10 и Windows Server 2016 вы не наблюдаете этой ошибки, и код выполняется правильно. Эта разница может быть связана с различиями в способе обработки PowerShell строк кода в зависимости от версии операционной системы.
Анализ ситуации
-
Интерпретация блоков кода:
PowerShell использует две основные модели парсинга: режим выражений и режим аргументов. Различия в этих режимах могут приводить к тому, что одни конструкции успешно выполняются на одних версиях ОС и проваливаются на других. Ваша проблема, скорее всего, обусловлена тем, что PowerShell на старых версиях Windows применяет более строгие правила парсинга, что требует наличия открывающей фигурной скобки на той же строке, что и условие IF. -
Фигурные скобки и разбиение строк:
По умолчанию PowerShell требует, чтобы открывающая фигурная скобка была размещена на одной строке с конструкцией IF. В случае, если она стоит на следующей строке, это может привести к интерпретации кода, которая выдает ошибку. Чтобы избежать подобных проблем, рекомендуется всегда размещать открывающую скобку на той же строке, что и условие IF, вне зависимости от версии Windows. -
Использование обратной кавычки:
Как временное решение, вы можете использовать обратную кавычку (`) в конце строки, чтобы указать, что команда продолжается на следующей строке. Однако стоит быть осторожным при использовании этого подхода, так как он может сделать ваш код менее читабельным и сложным в отладке.
Заключение
Проблема, с которой вы столкнулись, связана с различиями в способе парсинга кода PowerShell на разных версиях Windows. Чтобы обеспечить совместимость и избежать ошибки «Отсутствует блок операторов», рекомендуется придерживаться следующих практик:
- Всегда размещайте открывающую фигурную скобку на той же строке, что и условие IF.
- Избегайте использования многострочных здесь-строк (here-string) внутри условных операторов, если это возможно. Вместо этого используйте однострочные строки.
- Используйте обратные кавычки с осторожностью, если вы решите использовать многострочные конструкции, но старайтесь минимизировать их использование для улучшения читабельности кода.
Соблюдение этих рекомендаций поможет вам избежать нежелательных ошибок и улучшить стабильность ваших скриптов PowerShell.