PowerShell | Get-ChildItem для функции через конвейер не предоставляет все элементы - PullRequest
0 голосов
/ 29 мая 2020

Из-за того, что Azure Dev Ops конвертирует LF в CRLF при развертывании, мне нужно создать настраиваемую функцию, которая будет искать файлы. sh и преобразовывать их обратно в то, как они хранятся в репо (LF). Этот код я получил нормально, однако я ДЕЙСТВИТЕЛЬНО хочу создать потрясающую функцию. Я могу выполнить рекурсивный поиск одного get-childitem файлов. sh, а затем передать его моей настраиваемой функции, которая вернет их в правильный формат.

Моя проблема в том, что я, get-childitem и функции не ладят.

Чтобы сосредоточить внимание только на основной проблеме, здесь приведена чрезмерно упрощенная c примерная функция:

Function List-Items {
    param (
        [Parameter(ValueFromPipeline = $true)]$items
    )

    Write-Output "Item Count: $($items | Measure-Object | select -ExpandProperty Count)"
    foreach ($item in $items) {
        Write-Output "Item: $($item)"
    }
}

Я вызываю ее, используя:

dir c:\temp\ | List-Items

Однако, несмотря на то, что с помощью этой команды явно 52 элемента: dir c:\temp\ | Measure-Object

Функция видит только последнюю запись из этих 52. Как мне получить доступ ко всем 52 элементам в моей пользовательской функции списков ?

Ответы [ 2 ]

1 голос
/ 29 мая 2020

Это ожидаемое поведение. На самом деле, расширенная функция в PowerShell имеет три отдельных блока :

  • begin - выполняется один раз перед конвейером начинает выполнение
  • process - запускается один раз для каждого элемента ввода, привязанного к конвейеру
  • end - запускается один раз после командлет восходящего потока завершена отправка ввода

Когда вы не указываете ни один из этих отдельных блоков, а просто имеете одно тело функции, как в вашем примере:

Function List-Items {
    param (
        [Parameter(ValueFromPipeline = $true)]$items
    )

    # Do stuff with $items

}

Это фактически эквивалентно:

Function List-Items {
    param (
        [Parameter(ValueFromPipeline = $true)]$items
    )

    end {
        # Do stuff with $items
    }
}

Другими словами, тело функции по умолчанию действует как блок end, поэтому вы видите только последнее значение, привязанное к $items.

To исправьте это, явно укажите блок process:

Function List-Items {
    param (
        [Parameter(ValueFromPipeline = $true)]$items
    )

    process {
        foreach ($item in $items) {
            Write-Output "Item: $($item)"
        }
    }
}
1 голос
/ 29 мая 2020

Вам нужен блок процесса, который запускается один раз для каждого переданного элемента.

function hi { 
  param([Parameter(ValueFromPipeline=$True)]$inputvalue)

  process { 
    $inputvalue.count 
  } 

}

1,2,3 | hi

1
1
1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...