IT

첫 번째 오류가 발생했을 때 PowerShell 스크립트를 중지하는 방법

itgroup 2023. 4. 8. 08:23
반응형

첫 번째 오류가 발생했을 때 PowerShell 스크립트를 중지하는 방법

중인 명령어 중 하나: PowerShell 스크립트)가 실패했을 때 하고 싶다.set -e Powershell 명령어를 사용하고 있습니다Powershell명령어).New-Object System.Net.WebClient및 프로그램(.\setup.exe를 참조해 주세요.

$ErrorActionPreference = "Stop"(레틀릿)

, EXE의 「」, 「EXE」를 할 필요가 있습니다.$LastExitCode모든 exe 호출 후 직접 확인하고 실패 여부를 판단합니다.유감스럽게도 Windows에서는 EXE가 "성공" 또는 "실패" 종료 코드에 대해 크게 일치하지 않기 때문에 PowerShell이 도움이 될 수 없다고 생각합니다.대부분은 성공을 나타내는 UNIX 표준 0을 따르지만 모두 성공하지는 않습니다.블로그 투고에서 Check Last Exit Code 함수를 확인하십시오.유용하게 쓰실지도 몰라요.

할 수 예요.$ErrorActionPreference = "Stop"를 참조해 주세요.

「」$ErrorActionPreferenceContinue이 때문에 에러 발생 후에도 스크립트가 계속 진행됩니다.

안타깝게도 New-RegKeyClear-Disk와 같은 버그가 많은 cmdlet으로 인해 이러한 답변은 모두 충분하지 않습니다.나는 현재 다음 코드에 대해 파일명을 정했다.ps_support.ps1:

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
function ThrowOnNativeFailure {
    if (-not $?)
    {
        throw 'Native Failure'
    }
}

powershell 뒤에 .CmdletBinding ★★★★★★★★★★★★★★★★★」Param파일(존재하는 경우)은 다음과 같습니다.

$ErrorActionPreference = "Stop"
. "$PSScriptRoot\ps_support.ps1"

는 중복되었습니다.ErrorActionPreference = "Stop"은은의의 의다다다다다내가 바보짓을 해서 어떻게든 할 수 있다면ps_support.ps1★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★!

는 ★★★★★★★★★★★★를 보관하고 있다.ps_support.ps1sublic의 에, 의 「repo/sublic」의 , 「repo/sublic」의 위치에 따라, 닷될 수 ..ps1을 사용하다

모든 네이티브콜은 다음 처리를 받습니다.

native_call.exe
ThrowOnNativeFailure

이 파일을 닷 소스에 저장함으로써 powershell 스크립트를 작성할 때 제정신을 유지할 수 있었습니다. :- )

@alastairtree의 답변에 대한 약간의 변경:

function Invoke-Call {
    param (
        [scriptblock]$ScriptBlock,
        [string]$ErrorAction = $ErrorActionPreference
    )
    & @ScriptBlock
    if (($lastexitcode -ne 0) -and $ErrorAction -eq "Stop") {
        exit $lastexitcode
    }
}

Invoke-Call -ScriptBlock { dotnet build . } -ErrorAction Stop

주요 차이점은 다음과 같습니다.

  1. 동사운(동사운)을 흉내내다)을합니다.Invoke-Command)
  2. 는, 콜 오퍼레이터를 커버로 사용하고 있는 것을 나타내고 있습니다.
  3. 를 내다 -ErrorAction in
  4. 새 메시지에서 예외를 발생시키지 않고 동일한 종료 코드를 사용하여 종료합니다.

powershell 함수와 exe를 호출하기 위해서는 약간 다른 오류 처리가 필요하며 스크립트에 실패했음을 발신자에게 알려야 합니다.★★★★★★★★★★★★★★의 꼭대기에 이 있다.Exec라이브러리 Psake에서 아래 구조의 스크립트는 모든 오류에서 중지되며 대부분의 스크립트의 기본 템플릿으로 사용할 수 있습니다.

Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"


# Taken from psake https://github.com/psake/psake
<#
.SYNOPSIS
  This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
  to see if an error occcured. If an error is detected then an exception is thrown.
  This function allows you to run command-line programs without having to
  explicitly check the $lastexitcode variable.
.EXAMPLE
  exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
#>
function Exec
{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
        [Parameter(Position=1,Mandatory=0)][string]$errorMessage = ("Error executing command {0}" -f $cmd)
    )
    & $cmd
    if ($lastexitcode -ne 0) {
        throw ("Exec: " + $errorMessage)
    }
}

Try {

    # Put all your stuff inside here!

    # powershell functions called as normal and try..catch reports errors 
    New-Object System.Net.WebClient

    # call exe's and check their exit code using Exec
    Exec { setup.exe }

} Catch {
    # tell the caller it has all gone wrong
    $host.SetShouldExit(-1)
    throw
}

powershell은 처음이지만 이것이 가장 효과적인 것 같습니다.

doSomething -arg myArg
if (-not $?) {throw "Failed to doSomething"}

2021년에 오시는 분들을 위해 cmdlet과 프로그램을 모두 커버하는 솔루션입니다.

function CheckLastExitCode {
    param ([int[]]$SuccessCodes = @(0))

    if (!$?) {
        Write-Host "Last CMD failed $LastExitCode" -ForegroundColor Red
        #GoToWrapperDirectory in my code I go back to the original directory that launched the script
        exit
    }

    if ($SuccessCodes -notcontains $LastExitCode) {
        Write-Host "EXE RETURNED EXIT CODE $LastExitCode" -ForegroundColor Red
        #GoToWrapperDirectory in my code I go back to the original directory that launched the script
        exit
    } 
    
}

이렇게 쓸 수 있어요

cd NonExistingpath
CheckLastExitCode

내가 아는 한, 파워셸은 호출하는 하위 프로그램에 의해 반환되는 0이 아닌 종료 코드를 자동으로 처리하지 않습니다.

지금까지 제가 아는 유일한 해결 방법은bash -e는, 외부 커맨드에 을 실시할 때마다, 이 체크를 추가하는 것입니다.

if(!$?) { Exit $LASTEXITCODE }

저도 같은 걸 찾으러 왔어요$ErrorActionPreference="Stop"은 종료하기 전에 오류 메시지(마이너스)를 보고 싶을 때 셸을 즉시 삭제합니다.배치 감성에 의존:

IF %ERRORLEVEL% NEQ 0 pause & GOTO EOF

이것은 특정 PS1 스크립트와 거의 동일하게 동작하는 것을 알았습니다.

Import-PSSession $Session
If ($? -ne "True") {Pause; Exit}

단순한 재투구가 효과가 있는 것 같네요

param ([string] $Path, [string] $Find, [string] $Replace)
try {
  ((Get-Content -path $Path -Raw) -replace $Find, $Replace) | Set-Content -Path $Path
  Write-Output Completed.
} catch {
  # Without try/catch block errors don't interrupt program flow.
  throw
}

정상적으로 실행된 후에만 출력 완료가 표시됩니다.

리다이렉트stderr로.stdout다른 명령어/스크립트 블록 래퍼 없이 트릭을 실행하는 것 같습니다만, 왜 그렇게 동작하는지는 설명할 수 없습니다.

# test.ps1

$ErrorActionPreference = "Stop"

aws s3 ls s3://xxx
echo "==> pass"

aws s3 ls s3://xxx 2>&1
echo "shouldn't be here"

명령어가 「명령어」).aws s3 ...$LASTEXITCODE = 255)

PS> .\test.ps1

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
==> pass

언급URL : https://stackoverflow.com/questions/9948517/how-to-stop-a-powershell-script-on-the-first-error

반응형