jpm*_*c26 3 powershell parameter-passing
我有一个返回哈希表的命令.像这样,例如:
function Get-TestArgs() { return @{a=1;b=2;c=3} }
Run Code Online (Sandbox Code Playgroud)
我想将其返回值用作我的其他函数的参数:
function Test($a, $b, $c) {
Write-Host 'A' $a
Write-Host 'B' $b
Write-Host 'C' $c
}
Run Code Online (Sandbox Code Playgroud)
这可以通过PowerShell的splatting功能实现:
$testargs = @{a=1;b=2;c=3}
Test @testargs
Run Code Online (Sandbox Code Playgroud)
问题是我不想将哈希值分配给中间变量.
我想到的是这些方面的东西:
Test (some splat syntax)(Get-TestArgs)
Run Code Online (Sandbox Code Playgroud)
显然,这不起作用,因为它只是创建一个包含哈希的数组并传递:
Test @(Get-TestArgs)
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这个目标?
我正在编写将手动执行的指令.这些说明将调用脚本,但在调用之间仍有一些手动干预.因此,我希望尽量减少命令,以减少出现问题的风险,例如变量是其他命令或输入错误的遗留物.
我认为没有变量就可以使用splatting.但是,实现您正在寻找的东西的解决方法很少.
编写一个包装函数,该函数将采用哈希表并调用"真实"函数.如果你想直接调用这个函数Get-TestArgs,你可以使用TestInner.
function Get-TestArgs() { return @{a=1;b=2;c=3} }
function TestInner ($a, $b, $c)
{
write-host "a=" $a
write-host "b=" $b
write-host "c=" $c
}
function Test ($hash) {
return TestInner @hash
}
Test (Get-TestArgs)
TestInner 1 2 3
Run Code Online (Sandbox Code Playgroud)设计你的函数,使每个函数都将哈希表作为唯一参数 - 它是1的简化版本.它看起来有点难看 - 你只能Test通过查看它的声明来确定所需的参数.
function Test ($hash)
{
write-host "a=" $hash.a
write-host "b=" $hash.b
write-host "c=" $hash.c
}
Test (Get-TestArgs)
Run Code Online (Sandbox Code Playgroud)使用2.中的方法,但为函数参数创建一个新类型,使其更加"类型安全":
add-type -TypeDefinition @"
public class TestArg {
public int a = 0;
public int b = 0;
public int c = 0;
}
"@
function Get-TestArgs() { return new-object -type "TestArg" -Property @{a=1;b=2;c=3} }
function Test ([TestArg] $o)
{
write-host "a=" $o.a
write-host "b=" $o.b
write-host "c=" $o.c
}
Test (Get-TestArgs)
Run Code Online (Sandbox Code Playgroud)利用参数集和管道.这与编写包装器类似,但目标函数也是包装器 - 根据参数集,它将正常执行或使用splatting再次调用自身,但使用不同的参数集.
function Test {
param(
[Parameter(ParameterSetName="set1",Position=0)][int]$a,
[Parameter(ParameterSetName="set1",Position=1)][int]$b,
[Parameter(ParameterSetName="set1",Position=2)][int]$c,
[Parameter(ParameterSetName="pipeline",ValueFromPipeLine=$true,Position=0)][Hashtable]$obj
)
if ($obj -ne $null) { return Test @obj }
write-host "a=" $a
write-host "b=" $c
write-host "c=" $c
}
Test (Get-TestArgs)
Get-TestArgs | Test
Test 1 2 3
Run Code Online (Sandbox Code Playgroud)根据您需要创建的函数数量以及打算如何调用它们,您可以选择其中一种解决方案.就个人而言,最后一个似乎是我最优雅的选择.而且我会使用管道:Get-TestArgs | Test在PowerShell中看起来比较自然Test (Get-TestArgs).例如,许多Azure PowerShell命令都是以这种方式工作的.
我相当确定这不能通过泼溅来完成,因为:
\n\n\n \n\n\n
我真的认为你能做的最好的事情就是:
\n\nfunction Test() {\n param($a, $b, $c)\n Write-Host \'A\' $a\n Write-Host \'B\' $b\n Write-Host \'C\' $c\n}\n\nfunction Get-TestArgs() { @(1,2,3) }\n\n$p = Get-TestArgs; Test @p\nRun Code Online (Sandbox Code Playgroud)\n