Как написать сценарий PowerShell, который принимает входные данные конвейера?
Я пытаюсь написать сценарий PowerShell, который может получить ввод конвейера (и, как ожидается, сделает это), но пытается что-то вроде
ForEach-Object {
# do something
}
не работает при использовании скрипта из командной строки следующим образом:
1..20 | .test.ps1
есть ли способ?
примечание: Я знаю о функциях и фильтрах. Это не то, что я ищу.
4 ответа:
это работает, и есть наверное и другие способы сделать это:
foreach ($i in $input) { $i }
17: 12: 42 PS>1..20/. \cmd-input. ps1
1
2
3
-- СНиП --
18
19
20найдите "powershell $input variable", и вы найдете дополнительную информацию и примеры.
Пара здесь:
функции и фильтры PowerShell PowerShell Pro!
(см. раздел "Использование специальной переменной PowerShell "$input"")
"Скрипты, функции и блоки скриптов имеют доступ к переменной $input, которая предоставляет перечислитель над элементами во входящем конвейере. "
или
$input gotchas " PowerBlog Дмитрия PowerShell и за его пределами
"... в основном $input в перечислителе, который обеспечивает доступ к конвейеру, который у вас есть."для командной строки PS, а не
командная строка DOSКомандный Процессор Windows.
в v2 вы также можете принять ввод конвейера (по propertyName или byValue), добавить псевдонимы параметров и т. д.:
function Get-File{ param( [Parameter( Position=0, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true) ] [Alias('FullName')] [String[]]$FilePath ) process { foreach($path in $FilePath) { Write-Host "file path is: $path" } } } # test ValueFromPipelineByPropertyName dir | Get-File # test ValueFromPipeline (byValue) "D:\scripts\s1.txt","D:\scripts\s2.txt" | Get-File - or - dir *.txt | foreach {$_.fullname} | Get-File
вы можете написать фильтр, который является частным случаем функции, вот так:
filter SquareIt([int]$num) { $_ * $_ }
или вы можете создать аналогичную функцию, например:
function SquareIt([int]$num) { Begin { # Executes once before first item in pipeline is processed } Process { # Executes once for each pipeline object $_ * $_ } End { # Executes once after last pipeline object is processed } }
вышеизложенное работает как интерактивная функция definiton или если в скрипте можно поставить точку в вашей глобальной сессии (или в другом скрипте). Однако ваш пример показал, что вам нужен скрипт, поэтому здесь он находится в скрипте, который можно использовать напрямую (не требуется расставлять точки):
--- Contents of test.ps1 --- param([int]$num) Begin { # Executes once before first item in pipeline is processed } Process { # Executes once for each pipeline object $_ * $_ } End { # Executes once after last pipeline object is processed }
С PowerShell V2, это немного изменяется с помощью "расширенных функций", которые включают функции с теми же функциями привязки параметров, что и скомпилированные командлеты. Смотрите это блоге для примера различий. Также обратите внимание, что в этом случае расширенные функции не используют $_ для доступа к объекту конвейера. С помощью расширенных функций объекты конвейера привязываются к параметру так же, как и к командлету.
ниже приведены простейшие возможные примеры скриптов / функций, которые используют конвейерный ввод. Каждый из них ведет себя так же, как конвейер для командлета "echo".
Как Скрипт:
# Эхо-Труба.пс1# Echo-Pipe2. ps1Begin { # Executes once before first item in pipeline is processed } Process { # Executes once for each pipeline object echo $_ } End { # Executes once after last pipeline object is processed }
foreach ($i in $input) { $i }
функции:
Function Echo-Pipe { Begin { # Executes once before first item in pipeline is processed } Process { # Executes once for each pipeline object echo $_ } End { # Executes once after last pipeline object is processed } } Function Echo-Pipe2 { foreach ($i in $input) { $i } }
например.
PS > . theFileThatContainsTheFunctions.ps1 # This includes the functions into your session PS > echo "hello world" | Echo-Pipe hello world PS > cat aFileWithThreeTestLines.txt | Echo-Pipe2 The first test line The second test line The third test line