2017-11-15 10 views
1

foreach-object 루프 (및 System.Net.WebClient)를 사용하여 파일 세트를 하나씩 다운로드하는 powershell 스크립트가 있습니다. 때때로 특정 파일의 소스 URL에서 404 오류가 발생합니다. 오류는 비언어적이어서이 유형의 오류가 발생하면 스크립트가 계속 진행됩니다. 문제는 파일 세트를 세트로 다운로드해야하며 모든 파일을 사용할 수 없다면 좋지 않다는 것입니다. 그래서 내가해야 할 일은 스크립트를 일시 중지하고 404 오류가 발생하면 다운로드를 다시 시도하는 것입니다. 이 문제가 발생하는 최선의 방법을 파악하는 데 문제가 있습니다. 다음은 다운로드 할 때 사용하는 코드입니다.Powershell 파일 다운로드를 다시 시도하면 404 오류가 발생합니다.

Get-Content $shaFile | Foreach-Object { ($_ -split " ", 2)[0] } | 
     Where-Object { ($adfs.$v.iniFile,$shaFile -NotContains $_) -and (Is-Match $_) } | Foreach-Object { 
      #$null=Download-File $w $_ $dir 

그래서이 나는 404와 같은 오류의 몇 가지 유형을 얻을하지 않는 한 내가하고 싶은 것은이 오류를 선택하고 시도 및 다운로드가 있습니다 .... 제대로 파일을 다운로드 : 원래 그것은 단지이 한 누락 된 파일을 다운로드하고 다운로드 할 때까지 계속 시도하십시오. 일반적으로 이것은 소스 URL이 여전히 게시 중이며 아직 복사 할 수없는 파일을 다운로드하려고하는 타이밍 문제로 인해 발생하는 것으로 보입니다. 따라서 오류를 감지하고 소스 URL이 다운로드 될 때까지 파일을 다운로드하려고 시도하면됩니다. 내가 생각해내는 것은 아래와 같습니다 :

Get-Content $shaFile | Foreach-Object { ($_ -split " ", 2)[0] } | 
     Where-Object { ($adfs.$v.iniFile,$shaFile -NotContains $_) -and (Is-Match $_) } | Foreach-Object { 

     try { 
      $null=Download-File $w $_ $dir 
     } 

     catch { 
      sleep 60 
      $null=Download-File $w $_ $dir 
      "Re-downloading missed file" 
    } 
    } 

그래서 나는이 스크립트가 오류가 발생하면 잠시 후에 다시 시도 할 것입니다. 그게 좋겠지 만 실제로 이동하기 전에 파일이 실제로 다운로드되었는지 확인하려고했습니다. 그래서 $ _가 목적지에 존재하지 않는다고 말하는 어떤 while 루프처럼, 그것이 계속 될 때까지 계속 다운로드하려고 노력합니다. 위의 코드에서 "Download-file"함수와 "Is-Match"함수를 호출합니다. 다운로드 파일은 System.Net.WebClient를 사용하여 웹 사이트에서 파일을 다운로드합니다.

나는 다음과 같은 작업 만이 처리 할 수있는 그것의 가장 좋은 방법은 잘 모르겠습니다 수 어쩌면 생각 :

Get-Content $shaFile | Foreach-Object { ($_ -split " ", 2)[0] } | 
      Where-Object { ($adfs.$v.iniFile,$shaFile -NotContains $_) -and (Is-Match $_) } | Foreach-Object { 
do{ 
    $Failed = $false 
    Try{ 
     $null=Download-File $w $_ $dir 
    } 
    catch { $Failed = $true } 
} while ($Failed) 

아니면 내가 할 수있는을 다음

Get-Content $shaFile | Foreach-Object { ($_ -split " ", 2)[0] } | 
       Where-Object { ($adfs.$v.iniFile,$shaFile -NotContains $_) -and (Is-Match $_) } | Foreach-Object { 
Try{ 
     $null=Download-File $w $_ $dir 
} 
    catch { 
    while ($error){ 
    Start-Sleep -s 60 
    $null=Download-File $w $_ $dir 
} 
} 
내가 코드를 테스트 할 수 있습니다

하지만, 파일이 모두있는 대부분의 시간에 오류를 아주 쉽게 테스트 할 수는 없습니다. 어쨌든 나는 여기에 어떤 도움을 주셔서 감사합니다. 미리 감사드립니다.

+1

[[HTTP404]는 일반적으로 서버 자체에서 요청한 리소스를 찾을 수 없음을 나타냅니다.] (https://en.wikipedia.org/wiki/HTTP_404). 다시 시도하지 않아도 문제가 해결됩니다. – TheIncorrigible1

답변

1

나는 이런 식으로 시도 할 것입니다. 다운로드가 실패 할 경우 Download-File에 대해 반환 된 객체가 null이라고 가정합니다. 실제로 어떻게 작동하는지 확인해야합니다. 실패한 다운로드를 시뮬레이션하려면 반환 된 객체를 Download-File에서 $ null로 다시 쓸 수 있습니다.

$maxRetries = 5 
$retryWaitSeconds = 60 
Get-Content $shaFile | Foreach-Object { ($_ -split " ", 2)[0] } | 
     Where-Object { ($adfs.$v.iniFile,$shaFile -NotContains $_) -and (Is-Match $_) } | Foreach-Object { 
      do { 
       $file = Download-File $w $_ $dir 
       #force the file download to fail 3 times for testing 
       foreach ($i in 1..3) { 
        $file = $null 
       } 

       #sleep if the file download failed. 
       if ($file -eq $null) { 
        start-sleep $retryWaitSeconds 
       } 
      } 
      while (($file -eq $null) -and ($retryCount -le $maxRetries)) #limit the maximum number of retries in case download will never succeed. 
     }