windows comandos Como parar um script do PowerShell no primeiro erro?




windows powershell como usar (5)

Eu quero que meu script do PowerShell pare quando qualquer um dos comandos que eu executo falhar (como set -e no bash). Estou usando os dois comandos do Powershell ( New-Object System.Net.WebClient ) e programas ( .\setup.exe ).


Answer #1

Você precisa de um tratamento de erro ligeiramente diferente para as funções do PowerShell e para chamar os exe, e você precisa ter certeza de dizer ao chamador do seu script que ele falhou. Construindo em cima do Exec partir da biblioteca Psake, um script que tenha a estrutura abaixo irá parar em todos os erros, e é utilizável como um template base para a maioria dos scripts.

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
}

Answer #2

Eu vim aqui procurando a mesma coisa. $ ErrorActionPreference = "Stop" mata meu shell imediatamente quando eu prefiro ver a mensagem de erro (pausa) antes de terminar. Recuando nas minhas sensibilidades de lote:

IF %ERRORLEVEL% NEQ 0 pause & GOTO EOF

Descobri que isso funciona praticamente da mesma maneira para o meu script ps1 em particular:

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

Answer #3

Você deve conseguir fazer isso usando a instrução $ErrorActionPreference = "Stop" no início de seus scripts.

A configuração padrão de $ErrorActionPreference é Continue , e é por isso que você está vendo seus scripts continuarem após a ocorrência de erros.


Answer #4

$ErrorActionPreference = "Stop" vai te levar a parte do caminho (isto é ótimo para cmdlets).

No entanto, para EXEs, você precisará verificar $LastExitCode após cada chamada exe e determinar se $LastExitCode falha ou não. Infelizmente, não acho que o PowerShell possa ajudar aqui, porque no Windows, os EXEs não são muito consistentes no que constitui um código de saída de "sucesso" ou "falha". A maioria segue o padrão UNIX de 0 indicando sucesso, mas nem todos o fazem. Confira a função CheckLastExitCode nesta postagem do blog . Você pode achar util.


Answer #5

Uma ligeira modificação na answer de @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

As principais diferenças são:

  1. ele usa o Verb-Noun (mimicando Invoke-Command )
  2. implica que ele usa o operador de chamada sob as tampas
  3. imita o comportamento -ErrorAction de cmdlets incorporados
  4. sai com o mesmo código de saída em vez de lançar exceção com nova mensagem




powershell