Windows PowerShell : Короткий синтаксис

OSzone.net » Microsoft » PowerShell » Windows PowerShell : Короткий синтаксис
Автор: Дон Джонс
Иcточник: TechNet Magazine
Опубликована: 08.08.2012

Одна из вещей, которую я люблю и ненавижу одновременно, — органичная гибкость Windows PowerShell. Во многом этот инструмент реализован как язык программирования. Если вы не программист, то можете легко игнорировать этот факт и обращаться с ним, как с инструментом командной строки.

Ну, не совсем уж игнорировать. Видите ли, в Windows PowerShell всегда есть три-четыре способа выполнения одной и той же задачи. Но вам достаточно найти лишь один способ, который гарантировано удовлетворяет ваши потребности. Вместе с тем, пытливый пользователь Windows PowerShell узнает о всех способах. Поэтому при изучении примеров, созданных другими людьми, вы сможете понять, что происходит.

Все дело в отношении

Псевдонимы — первое «быстрое решение», с которым вам придется столкнуться. Вот пример команды:

PS C:\> Get-WmiObject -class Win32_LogicalDisk -Filter "DriveType=3" |
>> Where-Object -FilterScript{ $_.FreeSpace / $_.Size -lt .1 } |
>> Select-Object -Property DeviceID,FreeSpace,Size
>>

Ее можно сократить так:

PS C:\>gwmi Win32_LogicalDisk -Fi "DriveType=3" |
>> ?{ $_.FreeSpace / $_.Size -lt .1 } |
>> SelectDeviceID,FreeSpace,Size
>>

Я воспользовался псевдонимами для обозначения имен команд и сократил длину параметров. Windows PowerShell позволяет урезать имена параметров, если урезанное имя позволяет однозначно определить, какой параметр имеется в виду. Это упрощает ввод с клавиатуры, но сильно усложняет чтение команд. Я рекомендую слушателям своих курсов всегда полностью указывать все имена при публикации примеров, сохранении в сценарии или при любом другом долгосрочном хранении команд. Потом в них будет проще разобраться.

Windows PowerShell ISE и большинство других редакторов позволяют вводить урезанную версию имени параметра и нажатием Tab вставлять полное имя. Так приходится меньше вводить с клавиатуры, а читабельность полученных команд остается на высоте. Я совсем не указал имена других параметров, потому что они позиционные. Иначе говоря, если я укажу все значения в правильном порядке, команда будет работать.

И в этом случае отсутствие имен затрудняет чтение. Большинство людей предпочтут, чтобы в сценарии указывались полные имена параметров. Использование полных имен параметров в некотором смысле упрощает задачу и вам, потому что не нужно помнить их порядок. При явном использовании имен порядок параметров не имеет значения.

Выражения в кавычках

Иногда требуется вставлять результат выражения в строку с кавычками. Это позволяет вставлять результат работы сценария. Один из способов выполнения этой задачи — сохранение результата в переменной, после чего надо заставить Windows PowerShell вставить переменные в строки с двойными кавычками. Windows PowerShell заменит переменную ее содержимым:

$disk = Get-WmiObject -class Win32_LogicalDisk -filter "DeviceID='C:'"
$freepercent = $disk.freespace / $disk.size * 100
Write-Host "Free space on drive C: at $freepercent percent"

Windows PowerShell также позволяет размещать в двойных скобках целое выражение. Синтаксис напоминает один из приемов работы в оболочке Unix. Это выглядит немного странно, но вы увидите, что это используется довольно часто:

$disk = Get-WmiObject -class Win32_LogicalDisk -filter "DeviceID='C:'"
Write-Host "Free space on drive C: at $($disk.freespace / $disk.size * 100) percent"

Я предпочитаю первую форму, потому что мне приходится работать с начинающими пользователями Windows PowerShell. Ее проще читать. На каждом этапе сценария выполняется одна операция, что также способствует пониманию.

Во второй форме используется много пунктуации, поэтому она сложнее для понимания. Вместе с тем, вторая форма технически более эффективна. В ней не создается переменной, которую Windows PowerShell приходится отслеживать. Также она требует вводить меньше текста с клавиатуры, что нравится большинству пользователей.

Создание объектов

Длинная форма снова оказывается кстати, когда нужно создать нестандартный объект:

$cs = Get-WmiObject -class Win32_ComputerSystem
$os = Get-WmiObject -class Win32_OperatingSystem
$obj = New-Object -TypeNamePSObject
$obj | Add-Member -MemberTypeNoteProperty -Name OSVersion -Value $os.version
$obj | Add-Member -MemberTypeNoteProperty -Name Mfgr -Value $cs.manufacturer
$obj | Add-Member -MemberTypeNoteProperty -Name Model -Value $cs.model
Write-Output $obj

Иногда я немного сокращаю эту форму за счет добавления команд Add-Member в один конвейер:

$cs = Get-WmiObject -class Win32_ComputerSystem
$os = Get-WmiObject -class Win32_OperatingSystem
$obj = New-Object -TypeNamePSObject
$obj | Add-Member -MemberTypeNoteProperty -Name OSVersion -Value $os.version –PassThru |
Add-Member -MemberTypeNoteProperty -Name Mfgr -Value $cs.manufacturer –PassThru |
Add-Member -MemberTypeNoteProperty -Name Model -Value $cs.model –PassThru

Недавно я перешел к немного другой форме, которая еще удобнее для чтения.

$cs = Get-WmiObject -class Win32_ComputerSystem
$os = Get-WmiObject -class Win32_OperatingSystem
$props = @{'OSVersion'= $os.version;
           'Mfgr'=$cs.manufacturer;
           'Model'=$cs.model}
$obj = New-Object -TypeNamePSObject -Property $props
Write-Output $obj

И на этот раз я предпочитаю этот длинный синтаксис из-за удобства чтения. Я работаю с новичками в деле применения Windows PowerShell, и для них читабельность критически важна для того, чтобы понимать, что происходит. Некоторые применяют следующий прием:

$obj = Select-Object OSVersion,Mfgr,Model
$obj.OSVersion = $os.version
$obj.Mfgr = $cs.manufacturer
$obj.Model = $cs.model
$obj

Результаты практически такие же, но текста меньше. Такое использование Select-Object скорее хакерский прием. В нем используется тот факт, что команду Select-Object можно заставить выбрать несуществующее свойство. При этом это свойство создается с пустым значением в качестве выходного объекта,

Мне очень больно видеть такое (зло)употребление командой Select-Object, и я в этом не одинок. Еще в 2008 году некоторые из моих коллег, носящих звание Windows PowerShell MVP высказывались против такого употребления. Независимо от личного отношения к этому приему, нужно научиться распознавать его, чтобы понимать, что при этом происходит.

В Windows PowerShell версии 3 можно делать так:

[pscustomobject]@{'OSVersion'= $os.version;
                  'Mfgr'=$cs.manufacturer;
                  'Model'=$cs.model}

Я пока не определился с отношением к такому синтаксису, но в целом все выглядит нормально. В нем сохраняется понятность, а печатать приходится меньше. Люди будут использовать его, поэтому его тоже надо научиться распознавать. Кажется, такой синтаксис еще и выполняется быстрее подробнее о нем можно почитать в блоге Джонатана Медда по адресу

Ярлыки объектов

В последнем приеме используются ярлыки — он похож на прием с выражениями в строках. Это совершенно легальный синтаксис программирования — он сложен только для новичков. Еще раз — в нем нет ничего «неправильного», поэтому надо привыкнуть к такому виду и понимать, что здесь происходит.

Допустим, вам нужно выполнить метод объекта, а затем что-то сделать с одним из свойств полученного в результате объекта:

$string = '  Hello   '
$string = $string.Trim()
$string.Length

Можно сократить все с помощью скобок. Сначала вычисляется выражение со скобками, а затем Windows PowerShell по сути заменяет скобки результатом:

$string = '   Hello   '
($string.Trim()).length

Здесь наворочено много пунктуации, поэтому сложно разобраться, что следует за чем и определить, что, собственно, происходит, но это вполне «законный» прием. Этот вариант может выполняться даже чуточку быстрее, потому что оболочке Windows PowerShell не нужно так много обращаться к переменной.

Извините за неоднозначность

В некотором смысле очень жаль, что Windows PowerShell не в состоянии предписать один-единственный способ выполнения задач. Тогда бы нам не пришлось изучать массу разных подходов. На сегодняшний день у нас есть оболочка, которая поддерживает много вариантов синтаксиса для выполнения одной и той же задачи. Полезно по крайней мере быть знакомым со всем вариантами синтаксиса. Тогда вы сможете работать с любыми попадающими вам под руки примерами.


Ссылка: http://www.oszone.net/18546/