2016-05-03 4 views
2

У меня проблема с игрушкой, которая кажется, что она должна быть простой. Я хотел бы иметь такую ​​функцию, как Join-Path, которая поддерживает канал. Назовите его Build-Path. Таким образом, эти заявления (которые мои тесты 1-4) должны быть эквивалентны:PowerShell: Позиционные параметры и ValueFromPipeline

Get-Location | Build-Path Test 

Get-Location | Build-Path -Right Test 

Build-Path -Left (Get-Location) -Right Test 

Build-Path (Get-Location) Test 

Я попробовал несколько вещей, и ближайший я могу получить эти две функции (взаимоисключающих):

A: Явная позиция по обоим значениям; сбой тест 1

function Build-Path 
(
    [Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)] 
    [String] $Left, 
    [Parameter(Mandatory=$true, Position=1)] 
    [String] $Right 
) 
{ 
    Join-Path $Left $Right 
} 

B: Нет положения на параметре трубопровода, положение справа 0; не проходит тест 4

function Build-Path 
(
    [Parameter(Mandatory=$true, ValueFromPipeline=$true)] 
    [String] $Left, 
    [Parameter(Mandatory=$true, Position=0)] 
    [String] $Right 
) 
{ 
    Join-Path $Left $Right 
} 

Я попытался с помощью ParameterSets в ряде направлений (не спасло мои попытки) без успеха, и я немного озадачен прямо сейчас.

Мысли?

+0

'$ left | Join-Path -ChildPath $ right' <- Я уверен, что Join-Path делает то, о чем вы просите. –

+0

@ RyanBemrose звучит педантично, но не использует позиционные параметры (т.е. $ left | Join-Path $ right) –

+1

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

ответ

3

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

Я даже попробовал переделка его с наборами параметров:

function Build-Path { 
[CmdletBinding(DefaultParameterSetName='Default',PositionalBinding=$false)] 
param(
    [Parameter(
     ParameterSetName='Default', 
     Mandatory=$true, 
     ValueFromPipeline=$true 
    )] 
    [Parameter(
     ParameterSetName='LooseyGoosey', 
     Mandatory=$true, 
     Position=0 
    )] 
    [String] 
    $Left, 

    [Parameter(
     ParameterSetName='Default', 
     Mandatory=$true, 
     Position=0 
    )] 
    [Parameter(
     ParameterSetName='LooseyGoosey', 
     Mandatory=$true, 
     Position=1 
    )] 
    [String] 
    $Right 
) 

    Join-Path $Left $Right 
} 

Чтобы увидеть, как PowerShell является обязательным параметрам, используйте Trace-Command:

Trace-Command -Name ParameterBinding -Expression { Build-Path (Get-Location) Test } -Verbose -PSHost 

Вы не столкнетесь с проблемами, независимо от того, как вы его фрагмент , Нет DefaultParameterSet? Набор параметров не может быть разрешен. Переключить настройки по умолчанию? Затем вы просто меняете, какие вызовы (ы) работают или нет.

Вы также не можете сделать -Right параметр а [String[]] массив, потому что во время привязки PowerShell будет пытаться принуждать, поэтому [String] по-прежнему будет принята и оценка.

DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Get-Location] 
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Get-Location] 
DEBUG: ParameterBinding Information: 0 : BIND cmd line args to DYNAMIC parameters. 
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Get-Location] 
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing 
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing 
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Build-Path] 
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Build-Path] 
DEBUG: ParameterBinding Information: 0 :  BIND arg [C:\Users\Briantist] to parameter [Right] 
DEBUG: ParameterBinding Information: 0 :   Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute] 
DEBUG: ParameterBinding Information: 0 :    result returned from DATA GENERATION: C:\Users\Briantist 
DEBUG: ParameterBinding Information: 0 :   BIND arg [C:\Users\Briantist] to param [Right] SKIPPED 
DEBUG: ParameterBinding Information: 0 :  BIND arg [C:\Users\Briantist] to parameter [Left] 
DEBUG: ParameterBinding Information: 0 :   Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute] 
DEBUG: ParameterBinding Information: 0 :    result returned from DATA GENERATION: C:\Users\Briantist 
DEBUG: ParameterBinding Information: 0 :   BIND arg [C:\Users\Briantist] to param [Left] SKIPPED 
DEBUG: ParameterBinding Information: 0 :  BIND arg [C:\Users\Briantist] to parameter [Right] 
DEBUG: ParameterBinding Information: 0 :   Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute] 
DEBUG: ParameterBinding Information: 0 :    result returned from DATA GENERATION: C:\Users\Briantist 
DEBUG: ParameterBinding Information: 0 :   BIND arg [C:\Users\Briantist] to param [Right] SKIPPED 
DEBUG: ParameterBinding Information: 0 :  BIND arg [C:\Users\Briantist] to parameter [Right] 
DEBUG: ParameterBinding Information: 0 :   Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute] 
DEBUG: ParameterBinding Information: 0 :    result returned from DATA GENERATION: C:\Users\Briantist 
DEBUG: ParameterBinding Information: 0 :   COERCE arg to [System.String] 
DEBUG: ParameterBinding Information: 0 :    Parameter and arg types the same, no coercion is needed. 
DEBUG: ParameterBinding Information: 0 :   BIND arg [C:\Users\Briantist] to param [Right] SUCCESSFUL 
DEBUG: ParameterBinding Information: 0 :  BIND arg [Test] to parameter [Right] 
DEBUG: ParameterBinding Information: 0 :   Executing DATA GENERATION metadata: [System.Management.Automation.ArgumentTypeConverterAttribute] 
DEBUG: ParameterBinding Information: 0 :    result returned from DATA GENERATION: Test 
DEBUG: ParameterBinding Information: 0 :   BIND arg [Test] to param [Right] SUCCESSFUL 
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Build-Path] 
DEBUG: ParameterBinding Information: 0 :  PROMPTING for missing mandatory parameters using the host