2012-08-23 3 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

감사합니다. 매우 도움이되었습니다. 작업을 사용하는 몇 가지 샘플 프로젝트를 작업하면서 조언을 계속하겠습니다. –

관련 문제