2012-08-23 76 views
1

我試圖更好地理解PowerShell如何處理作業。Powershell:Receive-Job中的意外結果

這兩種物品的職位幫助了很多:

然而,下面的示例腳本,我收到意想不到的效果,同時呼籲接收-工作。我期望每行都有結果,但有時我會看到每行多個結果或額外的空白回車。關於如何只寫出從每個作業從控制檯流入的信息的任何想法?

$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 
    } 
} 

輸出可...

 
Number is: 1 
Number is: 1 
Number is: 2 

或者有時候...

 
Number is: 1 
Number is: 2 
Number is: 1Number is: 2 
Number is: 1Number is: 2Number is: 2 

回答

3

你被很多過於複雜這一點。您不需要手動處理所有這些循環。您應該利用可用的cmdlet。這應該達到你想要的基本知識:

$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 
} 
+0

的感謝!你說得對,因爲我過度複雜了劇本。我傾向於在實驗中這樣做。你的例子是完美的,除非我想在作業運行時獲取數據,而不是等待工作?例如,我試圖在作業運行時(通過寫主機)將作業傳送到主PowerShell控制檯(這是腳本底部的所有循環的重點)。我是否正在走這條「這不是一份工作的目的/功能」的道路?在調用'Receive-Job'之前是否應該完成所有的工作? –

+1

這並不是說這不是工作的「目的」,只是這不是他們最擅長的,而且這不是您擁有的cmdlet支持。你可以做各種瘋狂的循環和完成檢查,並得到一些「流式」行爲的表象,但它會非常複雜和容易出錯。這是您的成本/收益決定。最好的工作是「我會去做這項工作,並在完成後處理結果。」如果你想要流式傳輸,你可以讓每個作業寫入不同的日誌文件,並開始一個「尾部」進程來傳輸每個日誌。 – latkin

+0

謝謝你,你一直很有幫助。在處理一些使用作業的示例項目時,我會記住您的建議。 –