我调用脚本:“TestArgs1 xxx -T”。在TestArgs1中,我调用TestArgs2,试图传递相同的参数。如果我使用:“TestArgs2 @args”,则交换机-T正确传递为true。此外,如果我将$ args复制到另一个数组并传递它,它的工作原理。但是如果我先创建自己的数组,(为了修改一些参数),switch -T将作为false传递。为什么是这样?如何正确传递switch参数?请参阅以下示例代码:
###### TestArgs1
Write-Host "#### pass incoming args ###"
TestArgs2 @args
Write-Host "#### copy incoming args ###"
$a = $args
TestArgs2 @a
Write-Host "#### pass created array ###"
$b = "xxx", "-T"
TestArgs2 @b
###### TestArgs2
function Main {
param ($n, [switch] $t, [switch] $d)
"n = $n"
"t = $t"
}
Main @args
The output of this is the follows:
#### pass incoming args ###
n = xxx
t = True
#### copy incoming args ###
n = xxx
t = True
#### pass created array ###
n = xxx
t = False
当我创建自己的数组并传递相同的参数时,t显示为false。
答案 0 :(得分:2)
PowerShell执行此操作是因为以下两个命令的行为不同:
Some-Command -Param
Some-Command "-Param"
在第一种情况下,使用名为Param的参数调用Some-Command,在第二种情况下使用具有值“-Param”的位置参数调用Some-Command。
通过一些挖掘,我们可以弄清楚PowerShell如何知道差异。
function foo { $args[0] }
foo -SomeParam | Get-Member -MemberType NoteProperty -Force
运行上述内容后,我们看到以下输出:
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
<CommandParameterName> NoteProperty System.String <CommandParameterName>=SomeParam
我们看到PowerShell在$ args中的值中添加了一个NoteProperty。我们可以从中得出结论,PowerShell在splatting时使用NoteProperty来决定数组中的值是作为值传递还是作为参数传递。
所以 - 一个我不推荐的解决方案 - 你可以在你的字符串中添加一个NoteProperty,它们就是真正的参数。我不推荐这个,因为它依赖于未记录的实现细节。
另一种解决方案是使用像我的foo函数这样的函数将语法开关转换为splats作为参数的值。这可能看起来像:
function Get-AsParameter { $args[0] }
$b = "xxx", (Get-AsParameter -T)
TestArgs @b
答案 1 :(得分:0)
我运行了你的脚本并为这三个人提供了相同的内容:
PS C:\> .\TestArgs1.ps1 xxx -T
#### pass incoming args ###
n = xxx
t = False
#### copy incoming args ###
n = xxx
t = False
#### pass created array ###
n = xxx
t = False
代码:
###### TestArgs2
function TestArgs2 {
param ($n, [switch] $t, [switch] $d)
"n = $n"
"t = $t"
}
###### TestArgs1
Write-Host "#### pass incoming args ###"
TestArgs2 @args
Write-Host "#### copy incoming args ###"
$a = $args
TestArgs2 @a
Write-Host "#### pass created array ###"
$b = "xxx", "-T"
TestArgs2 @b