Powershell non-positional, необязательные параметры
Я пытаюсь создать powershell (2.0) script, который будет принимать аргументы, которые следуют этому базовому шаблону:
.\{script name} [options] PATH
Где варианты - любое количество необязательных параметров - подумайте по строкам '-v' для подробного описания. Аргумент PATH будет просто любым аргументом, который передается последним, и является обязательным. Можно было вызвать script без параметров и только один аргумент, и этот аргумент будет считаться Путем. У меня возникли проблемы с настройкой списка параметров, который содержит только необязательные параметры, но также не является позиционным.
Этот быстрый script демонстрирует проблему, с которой я сталкиваюсь:
#param test script
Param(
$firstArg,
$secondArg,
[switch]$thirdArg,
[Parameter(ValueFromRemainingArguments = $true)]
$remainingArgs)
write-host "first arg is $firstArg"
write-host "second arg is $secondArg"
write-host "third arg is $thirdArg"
write-host "remaining: $remainingArgs"
При вызове так:
.\param-test.ps1 firstValue secondValue
Выходы script:
first arg is firstValue
second arg is secondValue
third arg is False
remaining:
Поведение, которое я пытаюсь создать, будет иметь оба аргумента, которые попадают в необязательные параметры и заканчиваются в переменной остальныхArgs.
Этот вопрос/ответ предоставил способ достижения желаемого поведения, но он работает только в том случае, если есть хотя бы один обязательный параметр, и только если он предшествует всем другим аргументам.
Я могу продемонстрировать это поведение, сделав firstArg обязательным и указав позицию 0:
#param test script
Param(
[Parameter(Mandatory=$true, Position = 0)]
$firstArg,
$secondArg,
[switch]$thirdArg,
[Parameter(ValueFromRemainingArguments = $true)]
$remainingArgs)
write-host "first arg is $firstArg"
write-host "second arg is $secondArg"
write-host "third arg is $thirdArg"
write-host "remaining: $remainingArgs"
Запустите с тем же вводом, что и раньше:
.\param-test.ps1 firstValue secondValue
Выход выглядит следующим образом:
first arg is firstValue
second arg is
third arg is False
remaining: secondValue
Первый обязательный аргумент присваивается, и все оставшееся происходит полностью.
Возникает вопрос: как настроить список параметров таким образом, чтобы все параметры были необязательными, и ни один из них не является позиционным?
Ответы
Ответ 1
Как насчет этого?
function test
{
param(
[string] $One,
[string] $Two,
[Parameter(Mandatory = $true, Position = 0)]
[string] $Three
)
"One = [$one] Two = [$two] Three = [$three]"
}
One
и Two
являются необязательными и могут указываться только по имени. Three
является обязательным и может быть предоставлен без имени.
Эти работы:
test 'foo'
One = [] Two = [] Three = [foo]
test -One 'foo' 'bar'
One = [foo] Two = [] Three = [bar]
test 'foo' -Two 'bar'
One = [] Two = [bar] Three = [foo]
Это не удастся:
test 'foo' 'bar'
test : A positional parameter cannot be found that accepts argument 'bar'.
At line:1 char:1
+ test 'foo' 'bar'
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [test], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,test
Это не гарантирует, что ваш обязательный аргумент помещается последним или не будет указан. Но он позволяет использовать основной шаблон использования.
Он также не допускает более одного значения в $Three
. Это может быть то, что вы хотите. Но если вы хотите рассматривать несколько неименованных параметров как часть $Three
, добавьте атрибут ValueFromRemainingArguments
.
function test
{
param(
[string] $One,
[string] $Two,
[Parameter(Mandatory = $true, Position = 0, ValueFromRemainingArguments = $true)]
[string] $Three
)
"One = [$one] Two = [$two] Three = [$three]"
}
Теперь такие вещи, как эта работа:
test -one 'foo' 'bar' 'baz'
One = [foo] Two = [] Three = [bar baz]
Или даже
test 'foo' -one 'bar' 'baz'
One = [bar] Two = [] Three = [foo baz]