2012-08-04 132 views
3

我试图获得一个在作业内部使用函数的简单工作示例。我已经设法将我的函数传递给用于我的工作的脚本块,但我似乎无法获取该函数的参数。Powershell:将参数传递给存储在变量中的函数

# concurrency 
$Logx = 
{ 
    param(
    [parameter(ValueFromPipeline=$true)] 
    $msg 
    )  
    Write-Host ("OUT:"+$msg) 
} 

# Execution starts here 
cls 
$colors = @("red","blue","green") 
$colors | %{ 
    $scriptBlock = 
    { 
     Invoke-Expression -Command $args[1] 
     Start-Sleep 3   
    } 

    Write-Host "Processing: " $_ 
    Start-Job -scriptblock $scriptBlock -args $_, $Logx 
} 

Get-Job 

while(Get-Job -State "Running") 
{ 
    write-host "Running..." 
    Start-Sleep 2 
} 

# Output 
Get-Job | Receive-Job 

# Cleanup jobs 
Remove-Job * 

下面是输出:

Processing: red 
Id    Name   State  HasMoreData  Location    Command 
--    ----   -----  -----------  --------    ------- 
175    Job175   Running True   localhost    ... 
Processing: blue 
177    Job177   Running True   localhost    ... 
Processing: green 
179    Job179   Running True   localhost    ... 
179    Job179   Running True   localhost    ... 
177    Job177   Running True   localhost    ... 
175    Job175   Running True   localhost    ... 
Running... 
Running... 
OUT: 
OUT: 
OUT: 

那么就证明OUT:X3在输出我的函数获取调用,但我还没有发现任何语法这使我可以获取该函数的参数。思考?

编辑:

注意,在肖恩的观察之下,我的回应,我尝试使用功能变量,因为使用传统的功能似乎并没有工作。如果有一种方法可以实现这一点,我将非常乐意不必将我的函数作为变量传递。

回答

3

答案是使用Start-Job的初始化参数。如果你在一个块中定义了所有的函数,并通过了它们可用的块。

解决方案在这篇文章中发现:

How do I Start a job of a function i just defined?

这是我的例子来自以前,现在的工作:

# concurrency 
$func = { 
    function Logx 
    { 
     param(
     [parameter(ValueFromPipeline=$true)] 
     $msg 
     )  
     Write-Host ("OUT:"+$msg) 
    } 
} 

# Execution starts here 
cls 
$colors = @("red","blue","green") 
$colors | %{ 
    $scriptBlock = 
    { 
     Logx $args[0] 
     Start-Sleep 9   
    } 

    Write-Host "Processing: " $_ 
    Start-Job -InitializationScript $func -scriptblock $scriptBlock -args $_ 
} 

Get-Job 

while(Get-Job -State "Running") 
{ 
    write-host "Running..." 
    Start-Sleep 2 
} 

# Output 
Get-Job | Receive-Job 

# Cleanup jobs 
Remove-Job * 
0

如果您不用关键字function作为函数名称的前缀,PowerShell并不知道如此对待它。正如你编写脚本一样,它基本上是一个带有特殊文本的变量。你的输出显示它只执行它在该变量内容中识别的命令:Write-Host "OUT:"

使用正确的语法会告诉PowerShell中它是一个功能,你有变量传递到它,你需要执行:


function Logx 
{ 
    param(
    [parameter(ValueFromPipeline=$true)] 
    $msg 
    )  
    Write-Host ("OUT:"+$msg) 
} 

然后,当你在脚本中调用它,你只需要使用Logx

+0

这似乎并没有工作,这就是为什么我会通过把我的函数变成一个变量的麻烦。当我将Logx作为一个传统函数并尝试用Logx $ args [0]代替调用表达式调用它时,我得到: 术语'Logx'不被识别为cmdlet,函数,脚本文件的名称,或者能够运行的程序。检查名称的拼写,或者如果包含路径,请验证 路径是否正确,然后重试。 – 2012-08-04 01:29:18

+0

根据我的理解,Start-Job启动另一个没有引用父实例中定义的函数的powershell实例。这是我试图解决的问题。 – 2012-08-04 02:01:23

0

到目前为止。必须用完,稍后再尝试。 PS:什么在ARGS获得通过[1],我得到的红了不少,

CategoryInfo   : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException 
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand 

这里是我到目前为止管理。

# concurrency 
$Logx = 
{ 
    param(
    [parameter(ValueFromPipeline=$true)] 
    $msg 
    )  
    Write-Host ("OUT:"+$msg) 
} 

# Execution starts here 
cls 
$colors = @("red","blue","green") 
$colors | %{ 
    & $scriptBlock = 
    { Invoke-Expression -Command $args[1] 
     Start-Sleep 3 
    } 

    Write-Host "Processing: " $_ 
    Start-Job -scriptblock $scriptBlock -ArgumentList @($_, $Logx) 
} 

# Get-Job 

while(Get-Job -State "Running") 
{ 
    write-host "Running..." 
    Start-Sleep 2 
} 

# Output 
Get-Job | Receive-Job 

# Cleanup jobs 
Remove-Job * 
+0

Args [0]和args [1]是传递给脚本块的参数的位置。所以args [1]是logx – 2012-08-04 14:27:49

相关问题