1

I call a script: "TestArgs1 xxx -T". From within TestArgs1, I call TestArgs2, trying to pass it the same arguments. If I use: "TestArgs2 @args", switch -T is correctly passed as true. Also if I copy $args to another array and pass it, it works. But if I create my own array first, (in order to modify some arguments), switch -T is passed as false. Why is this? How can I correctly pass the switch argument? See sample code below:

###### 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

When I create my own array and pass the same arguments, t shows up as false.

4

2 回答 2

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 函数这样的函数将语法开关转换为作为参数的值。这可能看起来像:

function Get-AsParameter { $args[0] }
$b = "xxx", (Get-AsParameter -T)
TestArgs @b
于 2013-10-10T20:28:13.010 回答
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
于 2013-10-10T20:22:54.337 回答