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のinitializescriptパラメーターを使用することです。ブロック内のすべての関数を定義し、ブロックを渡すと、それらが使用可能になります。

この投稿で解決策が見つかりました:

定義した関数のジョブを開始するにはどうすればよいですか?

これが以前の私の例で、現在は機能しています。

# 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

関数名の前にキーワードを付けないとfunction、PowerShellはそれをそのように扱うことを認識しません。スクリプトを作成したので、基本的には変数に特別なテキストが含まれています。出力が示すように、その変数のコンテンツ内で認識したコマンドのみを実行していますWrite-Host "OUT:"

正しい構文を使用すると、PowerShellは関数であり、実行する必要のある変数を渡す必要があることがわかります。


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

次に、スクリプト内でそれを呼び出すと、次のようになります。Logx

于 2012-08-04T00:49:17.680 に答える
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 に答える