1

私は、powershell がジョブを処理する方法をよりよく理解しようとしています。

これらの記事の投稿はどちらも大いに役立ちました。

ただし、次のサンプル スクリプトでは、Receive-Job の呼び出し中に予期しない結果が得られます。各行に結果が表示されることを期待していますが、1 行に複数の結果が表示されたり、余分な空白のキャリッジ リターンが表示されることがあります。各ジョブのコンソールからストリーミングされる情報だけを書き出す方法について何か考えはありますか?

$loops = 1..10
$jobs = new-object System.Collections.ArrayList

$loops | % {
    $jobs.add( 
        (start-job -ScriptBlock {
            param($list)
            $list | % {
                sleep -seconds (get-random -Maximum 3 -Minimum 1)
                write-host "Number is: $_"
            }
        } -ArgumentList (,$loops))
    ) | out-null
}


while ($jobs.count -gt 0)
{
    if ($jobs -ne $null)
    {
        $list = $jobs | ? { $_.HasMoreData -eq $true }
        $list | % { Receive-Job -Job $_ }
        $list2 = $jobs.Clone() | ? { $_.State -eq "Completed" }
        $list2 | % {
            $jobs.Remove($_) | out-null
        }
        $list = $null
    }
}

出力は...

番号: 1
番号: 1
数: 2

または時々...

番号: 1
数: 2
番号: 1番号: 2
数値: 1数値: 2数値: 2
4

1 に答える 1

3

あなたはこれをかなり複雑にしている。手動で処理するために、これらのループのすべてが必要なわけではありません。使用可能なコマンドレットを利用する必要があります。これにより、必要なものの基本が達成されます。

$loops = 1..10

$scriptBlock = {
  param($list)
  $list | % {
    sleep -seconds (get-random -Maximum 3 -Minimum 1)
    write-host "Number is: $_"
  }
}

$jobs = $loops | % { start-job -ScriptBlock $scriptBlock -ArgumentList (,$loops) }

$jobs | Wait-Job | Receive-Job

ただし、これにより、どのジョブが何を実行したかを知る方法がなくても、すべての出力がグループ化されます。そして、あなたが使用しているという事実は、あなたがWrite-Host実際にデータにアクセスすることができないことを意味します、それは単にスクリーンに印刷されます。

結果のジョブ出力を実際に保存または処理する場合は、次のようにすることができます。

$loops = 1..10

$scriptBlock = {
  param($list)
  $list | % {
    sleep -seconds (get-random -Maximum 3 -Minimum 1)
    "Number is: $_"  # don't use write-host, just output the string
  }
}

$jobs = $loops | % { start-job -ScriptBlock $scriptBlock -ArgumentList (,$loops) }

$jobs | Wait-Job  # wait for all jobs to be complete
$jobs |%{
   $output = $_ | Receive-Job
   # process $output here, do what you want with it
}
于 2012-08-23T03:37:11.707 に答える