PoshCode ( http://poshcode.org/3226) 에서 Get-WebFile 스크립트를 살펴보면 다음과 같은 이상한 충돌을 발견했습니다.
$URL_Format_Error = [string]"..."
Write-Error $URL_Format_Error
return
다음과 반대되는 이유는 무엇입니까?
$URL_Format_Error = [string]"..."
Throw $URL_Format_Error
또는 더 나은 :
$URL_Format_Error = New-Object System.FormatException "..."
Throw $URL_Format_Error
내가 이해하는 것처럼 종료하지 않는 오류에는 Write-Error를 사용하고 오류는 종료하는 경우 Throw를 사용해야하므로 Write-Error 다음에 Return을 사용해서는 안됩니다. 차이가 있습니까?
답변
Write-Error중요하지 않은 오류를 사용자에게 알리려면 사용해야합니다. 기본적으로 콘솔에 오류 메시지가 빨간색 텍스트로 인쇄됩니다. 파이프 라인이나 루프가 계속되는 것을 막지는 않습니다. Throw반면에 종료 오류라고하는 것을 생성합니다. throw를 사용하면 파이프 라인 및 / 또는 전류 루프가 종료됩니다. 사실 trap또는 try/catch구조를 사용하여 종료 오류를 처리 하지 않으면 모든 실행이 종료됩니다.
당신이 설정 한 경우주의 할 점은있다 $ErrorActionPreference로"Stop" 하고 사용 Write-Error이됩니다 종료 오류를 생성 .
당신이 링크 한 스크립트에서 우리는 이것을 발견합니다 :
if ($url.Contains("http")) {
$request = [System.Net.HttpWebRequest]::Create($url)
}
else {
$URL_Format_Error = [string]"Connection protocol not specified. Recommended action: Try again using protocol (for example 'http://" + $url + "') instead. Function aborting..."
Write-Error $URL_Format_Error
return
}
해당 함수의 작성자가 해당 함수의 실행을 중지하고 화면에 오류 메시지를 표시하려고하지만 전체 스크립트의 실행을 중지하지 않으려는 것처럼 보입니다. 스크립트 작성자가 사용할 수는 throw있지만 try/catch함수를 호출 할 때 를 사용해야한다는 의미 입니다.
return함수, 스크립트 또는 스크립트 블록 일 수있는 현재 범위를 종료합니다. 이것은 코드로 가장 잘 설명됩니다.
# A foreach loop.
foreach ( $i in (1..10) ) { Write-Host $i ; if ($i -eq 5) { return } }
# A for loop.
for ($i = 1; $i -le 10; $i++) { Write-Host $i ; if ($i -eq 5) { return } }
두 가지에 대한 출력 :
1
2
3
4
5
여기에 하나 개 잡았다 사용 return하여 ForEach-Object. 예상대로 처리를 중단하지 않습니다.
추가 정보:
$ErrorActionPreference: about_Preference_Variablestry/catch: about_Try_Catch_Finallytrap: about_Trapthrow: about_Throwreturn: about_Return
답변
쓰기 오류 의 주요 차이점 cmdlet 및 던져 PowerShell의 키워드는 전자가 단순히이다 인쇄 받는 텍스트 표준 오류 스트림 (표준 오류) 후자는 실제로 동안 종료 된 실행 명령이나 함수의 처리, 후 처리를 오류 정보를 콘솔에 보내 PowerShell에 의해.
제공 한 예제에서 두 가지의 다른 동작을 관찰 할 수 있습니다.
$URL_Format_Error = [string]"..."
Write-Error $URL_Format_Error
return
이 예에서는 오류 메시지가 콘솔로 전송 된 후 스크립트 실행 return을 명시 적으로 중지 하기 위해 키워드가 추가 되었습니다. 반면 두 번째 예에서는return 종료가 암시 적으로 수행되므로 키워드가 필요하지 않습니다 throw.
$URL_Format_Error = New-Object System.FormatException "..."
Throw $URL_Format_Error
답변
중요 : 두 가지 유형의 종료 오류 가 있으며 현재 도움말 항목이 불행히도 충돌합니다 .
-
문 -terminating 오류, 특정 복구 할 수없는 상황에서 cmdlet에 의해 및 .NET 예외가 / PS 런타임 오류가 발생하는 식으로보고; 진술 만 종료 되고 기본적으로 스크립트 실행이 계속됩니다 .
-
스크립트는 -terminating : (더 정확하게 오류 실행 영역-종료를 중 하나에 의해 트리거 등)
Throw또는 에러 동작 환경 변수 / 파라미터 값을 통해 오차 다른 유형 중 하나를 확대하여이Stop.
잡히지 않으면 현재 런 스페이스 (스레드)를 종료합니다. 즉, 현재 스크립트뿐만 아니라 해당하는 경우 모든 호출자도 종료합니다.
PowerShell의 오류 처리에 대한 포괄적 인 개요는 이 GitHub 설명서 문제를 참조하십시오. .
이 포스트의 나머지 부분은 비 종료 대 진술 종결 에 중점을 둡니다. 오류 .
질문의 핵심에 중점을 둔 기존의 유용한 답변을 보완하려면 : 문장 종결 또는 비 종료 오류 보고 방법을 어떻게 선택 합니까 ?
Cmdlet 오류보고 에는 유용한 지침이 포함되어 있습니다. 실용 요약을 시도하겠습니다 .
비 종료 오류의 기본 개념 은 대규모 입력 세트의 “내결함성”처리를 허용 하는 것 입니다. 입력 객체 의 하위 세트 를 처리 하지 못하면 기본적으로 장기 실행 프로세스 를 전체적으로 중단해서는 안됩니다 . 자동 변수로 수집 된 오류 레코드를 통해보고 된대로 나중에 오류를 검사하고 실패한 개체 만 재 처리 할 수 있습니다 $Error.
-
cmdlet / 고급 기능인 경우 NON-TERMINATING 오류를 보고 하십시오.
- 파이프 라인 입력 및 / 또는 배열 값 매개 변수를 통해 MULTIPLE 입력 객체를 받아들입니다.
- 오류 SPECIFIC 입력 개체 발생 , AND
- 이러한 오류는 원칙적으로 추가 입력 개체의 처리를 예방하지 않습니다 ( 상황 에 따라 입력 개체가 없거나 이전 입력 개체가 이미 성공적으로 처리되었을 수 있음).
- 고급 기능에서
$PSCmdlet.WriteError()종료Write-Error하지 않는 오류를보고하는 데 사용 합니다 ( 불행히도 호출자의 범위 에서$?설정 되지 않음 – 이 GitHub 문제 참조 ).$False - 처리 종료되지 않는 오류 것은 :
$?가장 최근의 명령이보고 여부를 알려줍니다 적어도 하나의 종료되지 않는 오류가 발생했습니다.- 따라서,
$?존재$False한다는 것은 (빈이 아닌) 서브셋을 입력 개체가 올바르게 아마도 전체 세트를 처리하지 않았다. - 기본 설정 변수
$ErrorActionPreference및 / 또는 공통 cmdlet 매개 변수-ErrorAction는 오류 출력 동작 및 종료되지 않는 오류를 스크립트 종료 오류로 에스컬레이션해야하는지 여부에 따라 종료되지 않는 오류의 동작 (만)을 수정할 수 있습니다.
- 따라서,
- 고급 기능에서
-
다른 모든 경우에는 STATEMENT-TERMINATING 오류를 보고하십시오 .
- 특히 SINGLE 또는 NO 입력 개체 만 허용하고 NO 또는 SINGLE 출력 개체를 출력하거나 매개 변수 입력 만 가져 오고 주어진 매개 변수 값이 의미있는 작업을 방해 하는 cmdlet / 고급 기능에서 오류가 발생하는 경우 .
- 고급 기능에서는
$PSCmdlet.ThrowTerminatingError()명령문 종료 오류를 생성하기 위해 사용해야합니다 . - 반대로
Throw키워드 는 전체 스크립트 (기술적으로는 현재 스레드 ) 를 중단 시키는 스크립트 종료 오류를 생성합니다 . - 취급 성명 – 종료 오류를하십시오
try/catch핸들러 또는trap문을 사용할 수 있습니다 (이 수 와 함께 사용할 수 비 종료 오류)하지만, 참고 심지어 문 기본적으로 -terminating 오류가 실행 스크립트의 나머지 부분을 방지하지 않습니다. 종료하지 않는 오류 와 마찬가지로 이전 명령문이 명령문 종료 오류를 트리거했는지 여부를$?반영$False합니다.
- 고급 기능에서는
- 특히 SINGLE 또는 NO 입력 개체 만 허용하고 NO 또는 SINGLE 출력 개체를 출력하거나 매개 변수 입력 만 가져 오고 주어진 매개 변수 값이 의미있는 작업을 방해 하는 cmdlet / 고급 기능에서 오류가 발생하는 경우 .
안타깝게도 모든 PowerShell 자체 핵심 cmdlet이 다음 규칙에 따라 작동하는 것은 아닙니다 .
-
실패 할 가능성은 없지만
New-TemporaryFile(PSv5 +)는 파이프 라인 입력을 수락하지 않고 하나의 출력 개체 만 생성하더라도 실패하면 종료되지 않는 오류를보고합니다 . 그러나 최소한 PowerShell [Core] 7.0에서 수정되었습니다. 그러나이 GitHub를 참조하십시오. 문제 . -
Resume-Job의 도움이 주장이 지원되지 않는 작업 유형을 (통과 등으로 생성 된 작업으로Start-Job지원되지 않습니다, 때문에Resume-Job워크 플로 작업 에만 적용 작업)을 전달하면 종료 오류가 발생하지만 PSv5.1에서는 사실이 아닙니다.
답변
Write-Error함수 소비자가 -ErrorAction SilentlyContinue(또는 -ea 0)로 오류 메시지를 표시하지 않도록합니다 . throw필요한 동안try{...} catch {..}
try … catch를 Write-Error다음 과 함께 사용하려면
try {
SomeFunction -ErrorAction Stop
}
catch {
DoSomething
}
답변
Andy Arismendi의 답변에 추가 :
쓰기 오류 가 프로세스를 종료 할지 여부 는 $ErrorActionPreference설정에 따라 다릅니다 .
사소한 스크립트의 경우 빠르게 실패 $ErrorActionPreference = "Stop"하도록 권장되는 설정 입니다.
“오류와 관련하여 PowerShell의 기본 동작은 오류가 계속됩니다 … VB6″다음 오류시 이력서 다시 시작 느낌 “-ish”
( http://codebetter.com/jameskovacs/2010/02/25/the-exec-problem/에서 )
그러나 Write-Error통화가 종료됩니다.
사용하려면 쓰기 오류 에 관계없이 다른 환경 설정의 비 종료 명령으로, 당신이 사용할 수있는 공통 매개 변수 -ErrorAction 값 Continue:
Write-Error "Error Message" -ErrorAction:Continue
답변
코드를 읽는 것이 정확하면 맞습니다. 종료 오류는을 사용해야 throw하며 .NET 유형을 처리하는 경우 .NET 예외 규칙을 따르는 것이 좋습니다.
답변
