Иногда замечаю, что некоторые скриптописатели получают “поломанный” конвейер, когда данные из одной команды вышли, но никуда не пришли. Возьмём простой пример:
[↓] [vPodans] foreach ($n in 1..3) {$n}
1
2
3
[↓] [vPodans]
Тут всё просто, циклом foreach перебираются данные и выводятся на экран. Мы привыкли, что всё, что выводится на экран можно передать дальше на конвейер. В принципе, это правильно, за исключением ряда случаев, когда это не работает. Чтобы убедиться в этом – передадим вывод этой команды через конвейер на Set-Content:
[↓] [vPodans] foreach ($n in 1..3) {$n}
1
2
3
[↓] [vPodans] foreach ($n in 1..3) {$n} | Set-Content file.txt
An empty pipe element is not permitted.
At line:1 char:28
+ foreach ($n in 1..3) {$n} | <<<< Set-Content file.txt
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : EmptyPipeElement
[↓] [vPodans]
и мы получаем ошибку, что у нас пустой конвейер. Если написать простой проверочный фильтр:
filter Test-Input {'current $_ is: ' + $_}
и проверить, что у нас приходит с конвейера в этот фильтр, то вы получите такую же ошибку и можете долго гадать, почему так, на экране данные есть, а в конвейер ничего не поступает. Причиной этому является то, что flow control (не знаю, как это на русский первести) конструкции не транслируют свой вывод в конвейер и вот список этих конструкций:
-
If…Else
-
If…ElseIf
-
For
-
Foreach
-
While
-
Do…While
-
Do…Until
-
Switch
Чтобы при использовании этих конструкций вывод транслировался на конвейер их нужно заключить в подвыражение – $( ):
[↓] [vPodans] $(foreach ($n in 1..3) {$n}) | Set-Content file.txt
[↓] [vPodans] gc file.txt
1
2
3
[↓] [vPodans] $(foreach ($n in 1..3) {$n}) | Test-Input
current $_ is: 1
current $_ is: 2
current $_ is: 3
[↓] [vPodans]
я заключил цикл Foreach в подвыражение и теперь данные стали поступать на конвейер. Это хорошо видно по выводу фильтра Test-Input, который приведён выше. Вот таким нехитрым способом мы решили проблему пустых конвейеров 