将$ args传递给脚本与传递创建的数组的工作方式不同

时间:2013-10-10 19:05:50

标签: powershell subscript args

我调用脚本:“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。

2 个答案:

答案 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