纠正未传递给函数的参数值

时间:2019-03-18 15:48:17

标签: powershell

我有一个名为TestFunc.ps1的文件。其内容如下

import h2o

我这样称呼

Function TestFunc([string]$param1, [string]$param2)
{
    Write-Host "------------------"
    Write-Host $param1
    Write-Host $param2
    Write-Host "------------------"
}

TestFunc $param1 $param2 

输出如下

C:\Test\TestFunc.ps1 "Hello" "World"

我希望输出为

------------------


------------------

我在这里做什么错了?

2 个答案:

答案 0 :(得分:5)

参数是为函数范围而不是脚本定义的。

您需要的是Param部分:

param ([string]$param1, [string]$param2)

function TestFunc([string]$param1, [string]$param2) {
    Write-Host "------------------"
    Write-Host $param1
    Write-Host $param2
    Write-Host "------------------"
}
TestFunc $param1 $param2 

当然,具有重复的变量名会引起误解,但我只是一个测试函数。就您而言,您甚至根本不需要功能:

param ([string]$param1, [string]$param2)

Write-Host "------------------"
Write-Host $param1
Write-Host $param2
Write-Host "------------------"

或者:

param ([string]$param1, [string]$param2)

function TestFunc {
    Write-Host "------------------"
    Write-Host $param1
    Write-Host $param2
    Write-Host "------------------"
}
TestFunc

或者使用$args automatic variable,而不定义任何参数:

function TestFunc {
    Write-Host "------------------"
    Write-Host $args[0]
    Write-Host $args[1]
    Write-Host "------------------"
}
TestFunc foo bar

答案 1 :(得分:1)

互补 marsze's helpful and effective answer

PowerShell具有两种用于定义参数的大同等语法形式-保留了PSv5 + class的定义 [1]

注:为简便起见,参数列表位于下面的一行中;但是,两种语法形式都允许将单独的参数放在自己的行上。

  • 仅用于功能

    • 类似C / C#的:在参数{strong> ,之后的{strong> (...)内的 {分隔列表函数{em> name 和 开头function foo ($bar, $baz) { # ... } ;例如:

      { ... }
  • 也用于 脚本功能 ,以及 脚本块 ,,类似于匿名函数):

    • 特定于PowerShell的:在param(...)内的 using分隔的参数变量声明列表 >,它必须是 body 中的 第一条语句(除了注释和# --- Script foo.ps1 param($bar, $baz) # ... # --- Function # This example is fully equivalent to `foo ($bar, $baz) { ...` above. # Note that no () is needed after the function name. function foo { param($bar, $baz) # ... } # --- Script block & { param($bar, $baz) # ... } # arguments... 指令之外):

      $foo

为简洁起见,以下可选元素在上面省略了:

  • 关于单个参数声明

    • 键入;例如,将参数[int]声明为类型System.Int32[int] $foo):

      • [Parameter()]
    • 参数属性,通常但并非专门通过[Parameter(Mandatory=$true)] [int] $foo属性;除其他外,后者确定相关参数是否为强制;例如:

      • param(...)
  • [CmdletBinding()]语句上方

    • [object[]]属性,它使函数或脚本成为高级一个,其行为与(编译的)PowerShell cmdlet 相同-参见{{3 }}

简单(非高级)脚本和函数中,也是完全不声明任何参数 的选项,其中< strong>传递的所有参数都包含在about_Functions_Advanced 中,这是常规的PowerShell数组($args)。
您甚至可以使用声明的参数 combine $argsparam(...)然后仅包含那些未绑定到声明的参数的参数。

相反,在automatic $args variable中,从根本上只允许您传递绑定到声明的参数的参数。


何时选择哪种语法形式:

  • 脚本文件脚本块 必须使用param(...)语句-类似于C#的语法不是可用。

  • 功能可以技术上使用类似于C#的语法和[CmdletBinding()] 可互换除< / em>如果需要param(...)属性,则只有param(...)语法有效。

    • 也就是说,为了保持一致性和更容易的扩展性(使功能成为以后的高级功能),通常首选foo 1 2语法

    • 此外,经常使用类似C#的语法在调用函数时更容易导致语法混乱。 PowerShell cmdlet和函数的调用就像 shell命令(没有括号,用空格分隔的参数)一样,而不是C#方法;例如
      foo -bar 1 -baz 2(或foo(1, 2))而不是class


[1] function foo(s) a=parse.(Float64,split(s,'^')) length(a)>1 && return a[1]^a[2] a[1] end 定义中的方法声明必须使用类似C#的语法,并且不支持任何参数属性(仅在 properties上支持它们) )。就像本机.NET类型的方法一样,类方法也必须使用方法语法进行调用 -请参见advanced scripts and functions和帮助主题this answer