set -e
bash에서 와 같이 실행하는 명령이 실패하면 PowerShell 스크립트를 중지하고 싶습니다 . Powershell 명령 ( New-Object System.Net.WebClient
)과 프로그램 ( .\setup.exe
) 을 모두 사용 하고 있습니다 .
답변
$ErrorActionPreference = "Stop"
이 방법의 일부를 제공합니다 (즉, 이는 cmdlet에 효과적입니다).
그러나 EXE의 경우 $LastExitCode
모든 exe 호출 후 자신 을 확인 하고 실패 여부를 결정해야합니다. 불행히도 Windows에서는 EXE가 “성공”또는 “실패”종료 코드를 구성하는 요소와 크게 일치하지 않기 때문에 PowerShell이 여기에서 도움을 줄 수 없다고 생각합니다. 대부분의 성공을 나타내는 UNIX 표준 0을 따르지만 모두 그렇지는 않습니다. 이 블로그 게시물에서 CheckLastExitCode 함수를 확인하십시오 . 유용 할 수 있습니다.
답변
명령문을 사용하여이를 수행 할 수 있어야합니다. $ErrorActionPreference = "Stop"
스크립트 시작 부분에 을 .
기본 설정은 $ErrorActionPreference
입니다 Continue
. 오류가 발생한 후에도 스크립트가 계속 표시되는 이유입니다.
답변
안타깝게도 New-RegKey 및 Clear-Disk와 같은 버그가있는 cmdlet으로 인해 이러한 답변으로는 충분하지 않습니다. 나는 현재 나의 건강을 유지하기 위해 powershell 스크립트의 맨 위에 다음 줄을 정했다.
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
그런 다음 모든 기본 전화 가이 처리를 얻습니다.
native_call.exe
$native_call_success = $?
if (-not $native_call_success)
{
throw 'error making native call'
}
그 기본 통화 패턴은 천천히 간결 해지기 때문에 옵션을 더 간결하게 만들기 위해 선택해야합니다. 저는 여전히 파워 쉘 초보자이므로 제안을 환영합니다.
답변
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
}
답변
@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
주요 차이점은 다음과 같습니다.
- 동사-명사 (mimicing
Invoke-Command
)를 사용합니다. - 커버 아래에서 호출 연산자를 사용함을 의미합니다.
-
-ErrorAction
기본 제공 cmdlet의 동작 모방 - 새 메시지로 예외를 발생시키지 않고 동일한 종료 코드로 종료
답변
나는 powershell을 처음 사용하지만 이것이 가장 효과적인 것 같습니다.
doSomething -arg myArg
if (-not $?) {throw "Failed to doSomething"}
답변
나는 같은 것을 찾기 위해 여기에 왔습니다. $ ErrorActionPreference = “Stop”은 종료되기 전에 오류 메시지 (일시 중지)를보고 싶을 때 즉시 쉘을 종료합니다. 배치 감도로 폴백 :
IF %ERRORLEVEL% NEQ 0 pause & GOTO EOF
나는 이것이 내 특정 ps1 스크립트와 거의 동일하게 작동한다는 것을 알았습니다.
Import-PSSession $Session
If ($? -ne "True") {Pause; Exit}
