2010-05-21 3 views
1

У меня есть сценарий Powershell, который считывает значения из трубопровода:паров трубопровода в Powershell

PARAM (
    [Parameter(ValueFromPipeline = $true)] 
    $s 
) 

PROCESS { 
    echo "* $s" 
} 

прекрасно работает:

PS> my.ps1 Foo
* foo

Я бы хотел, чтобы у сценария был список значений по умолчанию, так как наиболее распространенное использование всегда будет использовать одни и те же значения и хранить em по умолчанию будет наиболее удобным. Я сделал обычное задание:

PARAM (
    [Parameter(ValueFromPipeline = $true)] 
    $s = 'bar' 
) 

PROCESS { 
    echo "* $s" 
} 

Опять же, работает просто отлично:

PS> my.ps1
* бар
PS> my.ps1 Foo
* Foo

Однако при настройке списка по умолчанию я возвращаю что-то совершенно разумное, но совсем не то, что хочу:

PARAM (
    [Parameter(ValueFromPipeline = $true)] 
    $s = @('bar', 'bat', 'boy') 
) 

PROCESS { 
    echo "* $s" 
} 

Результат:

PS> my.ps1
* бар летучая мальчик

я ожидал:

PS> my.ps1
* бар
* bat
* boy

Как я могу получить один вызов цикла процесса для каждого значения по умолчанию? (Это несколько отличается от того, как получить один вызов в Process и обернуть текущее тело в большом цикле foreach за $ s).

ответ

6

Это worky, как и следовало ожидать, как показано более явно это изменение в код:

PARAM ( 
    [Parameter(ValueFromPipeline = $true)] 
    $s = @('bar', 'bat', 'boy') 
) 

PROCESS { 
    $s | %{$_ + " is a " + $_.GetType().Name} 
} 

Что вы получаете смущен является особенностью PowerShell, где она сглаживает массивы, когда их просят оказать им строка, например:

PS> $arr = 1,2,3 
PS> "$arr" 
1, 2, 3 
PS> $OFS = ', ' 
PS> "$arr" 
1, 2, 3 

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

+0

Стрелять. Я надеялся, что не должен делать foreach на каждом входящем объекте. Спасибо. –

+2

В общем, вам нужно учесть коллекции, а не только скаляры для параметра, связанного с конвейером (по значению). Стандартный шаблон должен быть чем-то вроде 'Process {foreach ($ obj в $ pipeParam) {...}}' –

+0

Это звучит как солидный совет. Спасибо. –

-1

Вместо:

PROCESS { 
    echo "* $s" 
} 

сделать:

PROCESS { 
    $s | foreach-object { 
     "* $_" 
    } 
} 

и попытаться выйти из привычку использовать эхо (записи на выходе) как ничего не захваченной будет выход для вас.

+1

Мне действительно нужен один вызов процесса на объект из конвейера. Вот что я имел в виду в заключении в скобках в конце. Thx, хотя. –