스택 추적 없이 PowerShell에서 '벌거벗은' 오류 메시지를 표시하려면 어떻게 해야 합니까?
PowerShell에서 표준 오류에 쓰거나 다음과 같은 오류를 트랩하려면 어떻게 해야 합니까?
- 오류 메시지가 오류로 표시됩니다(TeamCity 및 Octopal에서 오류로 볼 수 있도록 표준 오류에 실제로 기록).
- 스택 추적 가비지가 사용자의 아름답고 간결한 오류 메시지를 혼동하지 않음
이 모든 세월 동안 난 살아남았어요throw오류를 입력하거나 다음을 통해 쓰기Write-Error하지만 저는 피곤하고 늙었고, 대본에서 간결한 오류 메시지를 하나 보고 싶습니다.저는 모든 조합을 시도해 왔습니다.trap,throw,Write-Error,그리고.-ErrorAction소용이 없습니다.
try {
throw "error" # Sample code for a stack overflow. In the theater
# of your mind, imagine there is code here that does something real and useful
} catch {
Write-Error "An error occurred attempting to 'do something.' Have you tried rebooting?"
}
다음은 제가 보고 싶은 사용자 환경입니다.
C:\> & .\Do-Something.ps1
An error occurred attempting to 'do something.' Have you tried rebooting?
C:\> ▏
대신에 나는 다음을 얻습니다.
C:\> & .\Do-Something.ps1
An error occurred attempting to 'do something.' Have you tried rebooting?
At line:1 char:1
+ Do-RealWork
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Do-RealWork
C:\> ▏
효과가 없는 것에 대한 서문:
기본 설정 변수 설정
$ErrorViewto 게가인적변에.'CategoryView'PowerShell이 대신 간결한 한 줄의 오류 표현을 출력하지만 오류 메시지가 일반적으로 포함되지 않기 때문에 이 표현이 항상 충분한 정보를 포함하지 않을 수 있습니다.Throw "..."반영되긴 했지만, 반대로Write-Error출력에 특정 정보가 포함되어 있지 않습니다.'CategoryView'시행 중입니다.PowerShell(Core) 7+는 이제 새로운 기능을 통해 보다 간결한 오류 형식(가장 간단한 경우 오류 메시지만 인쇄)으로 기본 설정됩니다.
$ErrorView납체,ConciseView이 출력은 상황에 따라 한 줄로 표시됩니다.
특히 스크립트에서 오류가 발생해도 다중 행입니다..*ps1에) a에서 또는합니다.function스크립트(프로파일 스크립트 포함)에서 점으로 표시됩니다. 이 경우 스크립트의 파일 경로, 소스 코드 줄 및 줄 번호를 보고하는 추가 줄이 오류 메시지 앞에 나옵니다.
PowerShell 코드가 콘솔(콘솔 호스트 사용)에서 실행되는 경우 외부의 stderr(표준 오류 스트림)에 무조건 기록되는 를 사용합니다.
[Console]::Error.WriteLine("An error occurred ... Have you tried rebooting?")
참고:
PowerShell ISE와 같은 콘솔 이외의 호스트에서는 작동하지 않습니다.
[Console]::Error.WriteLine()출력이 콘솔에서 빨간색으로 인쇄되지 않음
안타깝게도 PowerShell 내부(호스트 간)와 외부에서 모두 작동하는 단일 솔루션은 없습니다.
[Console]::Error.WriteLine()외부 환경을 위해 stderr에 올바르게 쓰는 동안 PowerShell 내부에서 출력을 캡처하거나 억제할 수 없으며 PowerShell 콘솔 호스트에서만 작동합니다.유하게사,
$host.ui.WriteErrorLine()모든 호스트에서 작동하지만 PowerShell의 스트림 시스템 외부에서도 작동하는 UI 방식이므로 PowerShell에서 출력을 캡처하거나 억제할 수 없습니다.
더 중요한 것은 외부 세계의 stderr에 쓰지 않는다는 것입니다.Write-Error이와 관련하여 아래 참조).PowerShell 내부에만 해당
Write-ErrorPowerShell의 오류 스트림에 쓰기 때문에 출력을 캡처/억제할 수 있습니다.
불행하게도, 만불도히행하지,,Write-Error(시끄러움을 제외하고) 이상하게도, stderr이 명시적으로 방향을 바꾸고 있지 않는 한, 외부 세계의 stderr에게 편지를 쓰지 않습니다 - 자세한 내용은 제 답변을 참조하십시오.
Peter(OP 자체)는 이에 대한 해결책을 제공합니다.
[Console]::ForegroundColor = 'red'
[Console]::Error.WriteLine("An error occurred ... Have you tried rebooting?")
[Console]::ResetColor()
sugneg의 유용한 답변은 함수 래퍼를 제공합니다.
다행히 PowerShell은 출력이 파일로 리디렉션되는 것을 감지하면 색 코드를 자동으로 생략합니다.
이전 답변의 아이디어를 기반으로 기본 제공되는 쓰기 오류 cmdlet을 사용자 지정 함수로 일시적으로 재정의할 수 있습니다.
# Override the built-in cmdlet with a custom version
function Write-Error($message) {
[Console]::ForegroundColor = 'red'
[Console]::Error.WriteLine($message)
[Console]::ResetColor()
}
# Pretty-print "Something is wrong" on stderr (in red).
Write-Error "Something is wrong"
# Setting things back to normal
Remove-Item function:Write-Error
# Print the standard bloated Powershell errors
Write-Error "Back to normal errors"
이를 통해 Powershell Functions가 cmdlet보다 우선한다는 사실을 활용할 수 있습니다.
https://technet.microsoft.com/en-us/library/hh848304.aspx
이것은 아름답고 간결한 오류 메시지를 보여줄 뿐만 아니라 TeamCity가 문제를 쉽게 감지할 수 있도록 하는 가장 우아한 접근 방식입니다.
저는 최근에 이 문제를 직접 해결해야 했기 때문에 여기에 자세히 설명된 Write-ErrorMessage 함수를 작성했습니다. https://intellitect.com/powershell-write-error-without-writing-stack-trace/
구체적으로, 저는 그 조합을 활용했습니다.
Write-Error -Message $err -ErrorAction SilentlyContinue
$Host.UI.WriteErrorLine($errorMessage)
PowerShell의 오류를 트랩하는 가장 좋은 방법은 다음을 사용하는 것입니다.
$Error[0].Exception.GetType().FullName
다음은 이 기능을 올바르게 사용하는 방법의 예입니다.기본적으로 스크립트가 실패하는 다양한 시나리오를 사용하여 PowerShell에서 수행하려는 작업을 테스트합니다.
다음은 일반적인 PowerShell 오류 메시지입니다.
PS C:\> Stop-Process -Name 'FakeProcess'
Stop-Process : Cannot find a process with the name "FakeProcess". Verify the process name and call the cmdlet again.
At line:1 char:1
+ Stop-Process -Name 'FakeProcess'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (FakeProcess:String) [Stop-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.StopProcessCommand
그런 다음 오류 메시지의 예외가 표시됩니다.
PS C:\> $Error[0].Exception.GetType().FullName
Microsoft.PowerShell.Commands.ProcessCommandException
다음과 같이 오류 메시지를 감지하도록 코드를 설정합니다.
Try
{
#-ErrorAction Stop is needed to go to catch statement on error
Get-Process -Name 'FakeProcess' -ErrorAction Stop
}
Catch [Microsoft.PowerShell.Commands.ProcessCommandException]
{
Write-Host "ERROR: Process Does Not Exist. Please Check Process Name"
}
위의 예에서 Powershell 표준 오류 대신 출력은 다음과 같습니다.
ERROR: Process Does Not Exist. Please Check Process Name
마지막으로 여러 캐치 블록을 사용하여 코드의 여러 오류를 처리할 수도 있습니다.또한 "블랭킷" 캐치 블록을 포함하여 처리하지 않은 모든 오류를 캐치할 수 있습니다.예:
Try
{
Get-Process -Name 'FakeProcess' -ErrorAction Stop
}
Catch [Microsoft.PowerShell.Commands.ProcessCommandException]
{
Write-Host "ERROR: Process Does Not Exist. Please Check Process Name"
}
Catch [System.Exception]
{
Write-Host "ERROR: Some Error Message Here!"
}
Catch
{
Write-Host "ERROR: I am a blanket catch to handle all unspecified errors you aren't handling yet!"
}
sugneg의 답변을 바탕으로 Write-Error를 커스텀 함수와 쉽게 교환하고 되돌릴 수 있도록 다음과 같은 함수를 작성했습니다.사용자가 PowerShell ISE에서 쓰기 오류를 호출하는지 확인하는 항목도 추가했습니다.
# Override the built-in cmdlet with a custom version
function New-ErrorFunc {
function Dyn($message){
param($message,$ErrorAction)
if($psISE){
$Host.UI.WriteErrorLine($message)
}
else{
[Console]::ForegroundColor = 'red'
[Console]::Error.WriteLine($message)
[Console]::ResetColor()
}
if($ErrorAction -eq 'Stop'){
Break
}
}
return ${function:Dyn}
}
function Set-ErrorFunc(){
param([bool]$custom=$true)
if($custom){
$dynfex= New-ErrorFunc
Invoke-Expression -Command "function script:Write-Error{ $dynfex }"
}
else {
$custom= Get-Command Write-Error | Where-Object {$_.CommandType -eq 'Function'}
if($custom){ Remove-Item function:Write-Error }
}
}
#User our Custom Error Function
Set-ErrorFunc
# Pretty-print "Something is wrong" on stderr (in red).
Write-Error "Something is wrong"
# Setting things back to normal
Set-ErrorFunc -custom $false
# Print the standard bloated Powershell errors
Write-Error "Back to normal errors"
Powershell 7은 '소음'을 억제하는 새로운 오류 보기 범주 'ConciseView'를 제공합니다.
파워셸:
$ErrorView = 'ConciseView'
Get-ChildItem -path 'C:\NoRealDirectory'
출력:
Get-ChildItem: Cannot find path 'C:\NoRealDirectory' because it does not exist.
언급URL : https://stackoverflow.com/questions/38064704/how-can-i-display-a-naked-error-message-in-powershell-without-an-accompanying
'programing' 카테고리의 다른 글
| PHP 치명적 오류 필요한 파일을 열지 못했습니다. (0) | 2023.08.30 |
|---|---|
| 마지막 프레임에서 CSS3 애니메이션 중지 (0) | 2023.08.30 |
| PowerShell을 사용하여 .reg 파일을 실행하는 방법은 무엇입니까? (0) | 2023.08.30 |
| 플렉스 용기에 나머지 높이 또는 너비 채우기 (0) | 2023.08.30 |
| Android 사용자 지정 단추, 텍스트 색상 변경 (0) | 2023.08.30 |