programing

PowerShell 및 프로세스 종료 코드

skycolor 2023. 8. 30. 21:32
반응형

PowerShell 및 프로세스 종료 코드

이 자체 답변 질문은 PowerShell의 프로세스 종료 코드를 처리하는 두 가지 측면을 다루려고 합니다.

  • PowerShell 코드에서 외부 프로세스(외부 프로그램 호출)에 의해 설정된 종료 코드를 어떻게 쿼리할 수 있으며, 이러한 종료 코드는 PowerShell의 오류 처리와 어떻게 통합됩니까?

  • 다른 사용자가 CLI(PowerShell Core) /(Windows PowerShell)를 통해 PowerShell을 호출할 때 호출 프로세스(예: 빌드/CI/자동화 서버 작업, 예약된 작업 또는 다른 셸)에 성공 대 실패를 전달하는 PowerShell 프로세스의 종료 코드를 결정합니다.

PowerShell(코어) 7.3.3 기준 현재

참고:

  • PowerShell 내부의 종료 코드 사용과 관련하여 이 답변은 외부(즉, 터미널 기반) 프로그램을 직접 호출하는 데 중점을 둡니다(상황에 따라 필요).&구문상의 이유로 연산자), 이는 일반적인 사용 사례입니다.

  • 외부 프로그램은 cmdlet을 통해 호출할 수도 있지만, 올바른 도구는 거의 없습니다(필요한 시기/적절한 시기에 대한 지침은 GitHub 문서 #19379 참조).

    • 주어진 시나리오에서 사용해야 하는 경우 종료 코드를 얻는 방법은 킬로파인디아의 답변을 참조하십시오.$LASTEXITCODE 경우 채워지지 않습니다).

PowerShell - 내부적으로 종료 코드 사용:

기본 PowerShell 명령이 일반적으로 프로세스 내에서 실행되는 PowerShell 내부에서는 외부 프로그램실행하는 하위 프로세스종료 코드 역할매우 제한적입니다.

  • 일반적으로 기본 PowerShell 명령은 종료 코드를 설정하지 않으며 종료 코드에 적용되지 않습니다.

  • PowerShell에는 종료 코드에 대한 추상적인 대응물이 있습니다: , 자동, 부울 성공 상태 변수:

  • 은 가장 에 오류가 있는지 하지만, 는 거의 사용되지 까지는 최가에실명오반만지여있다, 않는거사니습지되용의하장실로영제근에 하는 것만큼 보이기 입니다. 특히 버전 6.x까지는 명령을 포함하는 것처럼 중요하지 않아 보이는 것 때문입니다.(...) 재정$?$trueGitHub 이슈 #3359 참조 - 그리고 사용하기 때문입니다.Write-Error설정하지 .$?$falseGitHub 문제 #3629를 참조하십시오. 그러나 최종적으로 사용자 코드가 명시적으로 설정할 수 있는 기능을 제공하는 것은 향후 버전에 대해 녹색 불이 켜졌습니다.

  • 하는 동안에$?또한 외부 프로그램이 다음의 종료 코드를 보고했는지 여부를 반영합니다.0(성공을 거두기 위해, 만들기$? 고신$true) 또는 0이 아닌 종료 코드(일반적으로 신호 오류, 생성$? $false)는 특정 종료 코드를 정수로 포함하는 자동 변수이며, 해당 값은 다른 외부 프로그램(있는 경우)이 동일한 세션에서 호출될 때까지 유지됩니다.

    • 주의: 다음으로 인해cmd.exe의 문제, 배치 파일의 종료 코드가 신뢰성 있게 보고되지는 않지만, 당신은 그것을 해결할 수 있습니다.cmd /c <batch-file> ... `& exit다음 답변을 참조하십시오. GitHub 문제 #15143에서는 이 해결 방법을 PowerShell 자체에 구축할 것을 추가로 제안합니다.

    • 또한 v7.1까지 거짓 음성을 보고할 수 있습니다. 즉, 외부 프로그램이 종료 코드를 보고하는 경우0에 "stderr 출을성는하력동또시다에 PowerShell"을 포함하는 PowerShell .2>또는*> 답변과 GitHub 문제 #3996참조하십시오. 이 문제는 v7.2+에서 수정되었습니다.

    • 마지막으로 읽기 전용으로 취급하고 PowerShell 자체만 설정하도록 하는 이 가장 좋습니다. (기술적으로 변수는 쓰기 가능하며 글로벌 범위에 있으므로 수동으로 수정하려면 다음에 할당해야 합니다.)$global:LASTEXITCODE실수로 영향을 미치지 않는 일시적인 로컬 복사본을 만들지 않도록 합니다.)

  • 종료 오류나 종료되지 않는 오류와 달리 외부 프로그램의 0이 아닌 종료 코드는 $ErrorActionPreference 변수에 의해 자동으로 실행될 수 없다,값을 통해 스크립트 중단 선택'Stop'외부 프로그램이 0이 아닌 종료 코드를 보고하는 경우.

    • v7.3에는 실험 기능이 도입되었습니다.PSNativeCommandErrorActionPreferenceRFC #277의 논의를 기반으로 외부 프로그램을 PowerShell의 오류 처리에 더 잘 통합하기 위해.
      이 기능을 활성화하면 기본 설정 변수를 다음과 같이 설정할 수 있습니다.$true외부 프로그램이 0이 아닌 종료 코드를 보고할 때마다 PowerShell 오류를 트리거하려면 해당 오류는$ErrorActionPreference선호 변수입니다.즉, 와 함께$ErrorActionPreference = 'Stop'사실상, 0이 아닌 종료 코드를 보고하는 외부 프로그램은 스크립트를 중단시킵니다. (Stderr 출력은 어느 쪽이든 인쇄하며, 별도로 필요합니다.)2>$null침묵을 위해.)
      모든 실험적 특징으로서, 이것은 공식적인 특징이 될 수도 있고 아닐 도 있습니다.

PowerShell이 외부에서 호출될 때 종료 코드로 보고하는 내용을 제어하는 방법:

적어도 성공을 전달하는 종료 코드 설정(0) vs. 실패(일반적으로 0이 아님)는 PowerShell CLI(명령줄 인터페이스) - pwsh for PowerShell [Core] vs. powershell을 통해 예약된 작업이나 Jenkins와 같은 자동화 서버에서 PowerShell 코드가 전체적으로 성공했는지 여부를 외부 호출자에게 알리는 중요한 메커니즘입니다.exe for 윈도우즈 PowerShell.

CLI는 PowerShell 코드를 실행하는 두 가지 방법을 제공하며 를 사용하여 종료 코드를 설정할 수 있습니다.<n>원하는 종료 코드입니다.

  • -File <script> [args...]스크립트 파일의 경로를 예상합니다(*.ps1) 실행하고, 선택적으로 인수 뒤에 붙습니다.

    • 실행 중exit <n> 이러한 스크립트 파일 바로 안쪽(해당 스크립트에서 호출하는 다른 스크립트 내부가 아님)은 PowerShell 프로세스가 종료 코드를 다음과 같이 보고하도록 합니다.<n>.

    • 지정된 스크립트 파일이 암시적으로 또는 그냥 종료되는 경우exit(종료 코드 인수 없음), 종료 코드0는 보고됩니다.

  • -Command <powershell-code>하나 이상의 PowerShell 명령이 포함된 문자열이 필요합니다.

    • 안전하려면 다음을 사용합니다.exit <n>명령 문자열의 직접적인 부분으로 - 일반적으로 마지막 문으로.

종료 코드로 성공 여부를 확인하는 도구에서 코드를 호출한 경우 모든 코드 경로가 명시적으로exit <n>종료합니다.

주의: 처리되지 않은 스크립트 종료 오류로 인해 PowerShell 프로세스가 종료되는 경우 - CLI가 다음을 사용하여 호출되었는지 여부에 관계없이-File또는-Command종료 코드는 항상 입니다.

  • 스크립트 종료(치명적) 오류가 PowerShell 코드에서 생성됩니다.throw기본 PowerShell 오류의 심각성을 최소화합니다.
    -ErrorAction Stop또는$ErrorActionPreference = 'Stop'또는 를 눌러 스크립트를 강제로 종료합니다.

  • 종료 코드가 충분히 구체적이지 않은 경우(일반적으로 성공 대 실패만 전달해야 하기 때문에) 코드를 /문으로 묶어서 블록에서 사용할 수 있습니다.

PowerShell이 프로세스 종료 코드를 설정하는 방법에 대한 정확한 규칙은 복잡합니다. 아래 요약을 참조하십시오.


PowerShell이 프로세스 종료 코드를 설정하는 방법:

  • 처리되지 않은 스크립트 종료 오류가 발생할 경우 종료 코드는 항상1.

  • 를 사용하여 스크립트 파일 실행(*.ps1):

    • 스크립트직접 실행되는 경우,<n>종료 코드가 됩니다(네스트된 호출의 이러한 문은 유효하지 않습니다).

    • 그렇지 않으면 스크립트 실행 중에 종료되지 않거나 문 종료 오류가 발생한 경우에도 마찬가지입니다.

  • 를 사용하여 하나 이상의 문이 포함된 명령 문자열을 실행합니다.

    • 명령 문자열에 전달된 문(일반적으로 마지막 문) 중 하나로 문이 직접 실행되는 경우,<n>종료 코드가 됩니다.

    • 그렇지 않은 경우 마지막으로 실행된 문의 성공 상태가 종료 코드를 결정합니다.

      • 한다면$?다음과 같습니다.

        • $true-> 종료 코드0
        • $false-> 종료 코드1마지막으로 실행된 문이 0이 아닌 다른 종료 코드를 보고하는 외부 프로그램인 경우에도.
      • 명령 문자열의 마지막 문이 성공 대 실패 신호를 보낼 문이 아닐 수 있으므로 를 사용하여 종료 코드를 확실하게 제어합니다. 를 통해 특정 0이 아닌 종료 코드를 보고할 수도 있습니다.

        • 예를 들어, 외부 프로그램에 의해 보고된 종료 코드를 충실하게 중계하기 위해서는,; exit $LASTEXITCODE사용자가 전달하는-Command.

PowerShell 7.0 기준 불일치 및 위험 요소:

  • 틀림없이,-Command(-c)는 추상 대신 마지막 문의 특정 종료 코드를 보고해야 합니다.0대.1.예를 들어.pwsh -c 'findstr'; $LASTEXITCODE보고해야 합니다.2,findstr.exe의 특정 종료 코드, 추상 대신1GitHub 13501호를 참조하십시오.

  • 종료 코드 보고 기능*.ps1파일 / 파일-FileCLI 매개 변수:

    • 종료 코드를 의미 있게 설정하는 명시적인 명령문일 뿐입니다. 대신 스크립트에서 실행되는 마지막 명령문이 종료 코드를 결정해야 합니다(물론, 이 명령문은exit진술), POSIX 호환 셸의 경우와 마찬가지로, 그리고-Command비록 논의된 차선의 방식이긴 하지만.

    • 호출할 때*.ps1을 통해 스크립트 작성-File또는 다음을 통한 마지막 진술로서.-Command다음을 통해 종료되는 스크립트가 없는 경우 PowerShell의 종료 코드exit은 항상 (예외 / 제외)throw경우, 그것이 되는 곳.1).

    • 대조적으로, 세션에서 호출될 때, 다시.exit,$LASTEXICODE외부 프로그램(또는 기타)의 종료 코드를 반영합니다.*.ps1 종료 코드를 설정한 경우)가 마지막으로 실행되었습니다. 스크립트 내에서 실행되었든 이전에 실행되었든 상관없습니다.

    • 즉, 다음과 같습니다.

      • 와 함께-File와는 달리-Command종료 코드는 다음과 같이 설정됩니다.0부재 시에exit문(비정상적인 종료를 제외)
      • 세션에서 종료 코드(에 반영됨)$LASTEXITCODE)가 없는 경우 스크립트 전체에 대해 전혀 설정되지 않습니다.exit진술.
    • GitHub 이슈 #11712를 참조하십시오.

제 생각에 가장 쉬운 방법은ExitCode이와 같이:

$proc = Start-Process -PassThru cmd
Wait-Process -InputObject $proc
$proc.ExitCode

다음을 입력하여 사용해 보십시오.exit 1에서cmd창문추가 발급을 원하지 않는 경우Wait-Process당신은 간단히 통과할 수 있습니다.-Wait로.Start-Process제일선에

언급URL : https://stackoverflow.com/questions/57468522/powershell-and-process-exit-codes

반응형