2

我试图获得一个在工作中使用函数的简单工作示例。我已经设法将我的函数传递到用于我的工作的脚本块中,但我似乎无法获取函数的参数。

# 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 所证明的那样,我的函数被调用了,但我还没有找到任何允许我获取函数参数的语法。想法?

编辑:

请注意下面 Shawn 的观察和我的回复,我尝试使用函数作为变量,因为使用传统函数似乎不起作用。如果有办法让它工作,我会很高兴不必将我的函数作为变量传递。

4

3 回答 3

3

答案是使用Start-Job的initializationscript参数。如果您在一个块中定义所有函数并传递该块,它们将变为可用。

在这篇文章中找到了解决方案:

如何开始我刚刚定义的函数的工作?

这是我以前的示例,现在可以使用:

# 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 * 
于 2012-08-04T19:00:49.430 回答
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 * 
于 2012-08-04T12:21:22.620 回答
0

如果您不使用关键字function作为函数名称的前缀,PowerShell 不知道如何处理它。当您编写脚本时,它基本上是一个包含一些特殊文本的变量。正如您的输出所示,它仅执行它在该变量内容中识别的命令:Write-Host "OUT:".

使用正确的语法将告诉 PowerShell 它是一个函数,并且您有需要执行的变量要传递给它:


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

然后,当您在脚本中调用它时,您只需使用Logx

于 2012-08-04T00:49:17.680 回答