Найти в Дзене
System Administration

Конвейер в Powershell

Одним из фундаментальных (и функциональных) решений любой оболочки является конвейер. Конвейер это механизм оболочки, который позволяет вывод одной команды передавать на вход для другой. Конвейер в оболочке во многом похож на сборочную линию на заводе: он последовательно совершенствует что-то при прохождении между этапами. Как в следующем примере: В PowerShell конвейер вызывается символом вертикальной черты: | В примере командлет Get-Process создает объекты, представляющие реальные процессы в системе. У данных процессов есть свойства: имя, использование памяти, идентификатор процесса и ряд других. Командлет Get-Process генерирует вывод, символом конвейера мы передаем этот вывод на вход командлету Where-Object, который проверяет каждый входной элемент на соответствие условию, а именно: процесс потребляет менее 500kb оперативной памяти. Второй конвейер применяется для сортировки отфильтрованного списка процессов по возрастанию по свойству Id. Этот пример иллюстрирует значительный прогр
Оглавление

Одним из фундаментальных (и функциональных) решений любой оболочки является конвейер.

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

Использование двух конвейеров для фильтрации и сортировки вывода команды Get-Process
Использование двух конвейеров для фильтрации и сортировки вывода команды Get-Process

В PowerShell конвейер вызывается символом вертикальной черты: |

В примере командлет Get-Process создает объекты, представляющие реальные процессы в системе. У данных процессов есть свойства: имя, использование памяти, идентификатор процесса и ряд других. Командлет Get-Process генерирует вывод, символом конвейера мы передаем этот вывод на вход командлету Where-Object, который проверяет каждый входной элемент на соответствие условию, а именно: процесс потребляет менее 500kb оперативной памяти. Второй конвейер применяется для сортировки отфильтрованного списка процессов по возрастанию по свойству Id. Этот пример иллюстрирует значительный прогресс в возможностях конвейеров: PowerShell передает по конвейеру полноценные объекты, а не их текстовые представления. Напротив, все остальные оболочки передают данные между этапами в виде обычного текста. Извлечение значимого информация из вывода в виде открытого текста превращает использование конвейеров в боль - для этого вам нужно получить черный дан по grep \ sed \ awk \ cat. Ну и regexp, куда же без него. Выразить предыдущий пример в традиционной оболочке на основе Unix достаточно сложно. А в cmd.exe это практически невозможно.

Конвейер для фильтрации объектов

Используйте командлет Where-Object для фильтрации элементов выходных данных команды, которые соответствуют условию, которое вы описываете. Чтобы просмотреть все запущенные процессы, в имени которых есть слово «pwsh», можно использовать операторы -like \ -match :

Получение информации о процессе
Получение информации о процессе

Операторы -like \ -match имеют разную логику работы, но в данном примере подходят для нашей задачи.

Для каждого элемента на входе (который является результатом предыдущей команды) Командлет Where-Object сравнивает эти входные данные с указанным вами блоком сценария. В нашем случае блок сценария это проверка содержания слова pwsh в свойстве Name объекта процесса.

Если блок сценария возвращает значение True, затем командлет Where-Object передает объект. Блок сценария — это серия команд PowerShell, заключенных в фигурные скобки - { и }. Внутри блока скрипта можно писать любые команды PowerShell, которые возвращают $true или $false в конечном счете.

Конвейер для изменения объектов

Используйте конвейер для изменения состояния объектов или изменения самих объектов. Захотели вы остановить процесс notepad++, допустим

Остановка процесса
Остановка процесса

Конвейер для группировки объектов

Помимо фильтрации и изменения объектов, конвейер в PowerShell позволяет группировать объекты. Например, есть желание узнать количество файлов определенного расширения в каталоге:

Получение информации о файлах в переменную и группировка по свойству Extension (расширение)
Получение информации о файлах в переменную и группировка по свойству Extension (расширение)

Про $_

В сценарии фильтрации переменная $_ (или $PSItem) представляет текущий входной объект. Для каждого элемента из входящего массива в конвейер, PowerShell присваивает этот элемент переменной $_ (или $PSItem), а затем запускает блок сценария. Аналогично, данная переменная используется в командлете цикла ForEach-Object для доступа к текущему элементу цикла.

Использование встроенной переменной $_
Использование встроенной переменной $_

Как узнать перечень свойств объекта?

В примере я рассказывал про фильтрацию на основе свойств объектов, но тут перед нами встает вопрос - а как оперативно узнать свойства объектов? Для этой задачи можно использовать командлет Get-Member, например так:

-7

По умолчанию команда Get-Member возвращает тип объекта и перечень методов и свойств объекта, но я воспользовался фильтрацией через конвейер для отображения только свойств объекта.