Local 'set -e' para funções

6

Existe tal recurso ou pode ser emulado razoavelmente facilmente? Quero o mesmo comportamento, exceto que return onde set -e teria causado uma chamada para exit .

    
por PSkocik 05.06.2015 / 12:31

3 respostas

7

Sub shell pode ser útil.

func() {(set -e
        echo a
        ehco b
        echo c
)}

func
func
func

Este script produz:

a
script.sh: line 3: ehco: command not found
a
script.sh: line 3: ehco: command not found
a
script.sh: line 3: ehco: command not found

Alternativamente, você pode estar interessado em esta implementação do try / catch no bash .

    
por 05.06.2015 / 12:56
6

Com ksh93 , se você usar a sintaxe própria do ksh para a definição de funtion ( function f {...;} ), as opções e traps terão um escopo local. Então, você pode fazer:

function f {
  trap 'return 99' ERR
  set -e
  echo foo
  false
  echo never output
}
f
echo "f exited with status $?"

O que dá:

foo
f exited with status 99
    
por 05.06.2015 / 13:12
5

Você pode definir o ERR trap, que é executado sempre que um comando retorna um status diferente de zero.

No bash, é um pouco difícil porque os traps não são locais para funções. Por padrão, os traps não são herdados por subshells ou subfunções; chame set -E para alterar isso. Aqui está um código de demonstração.

#!/bin/bash

subroutine () {
  false
  echo "Subroutine continued after status $?"
}

trapper () {
  local i ret
  trap 'ret=$?
        echo "Command $BASH_COMMAND returned status $ret"
        for ((i=0; i<$((${#FUNCNAME[@]}-1)); i++)) do
          echo "  from ${FUNCNAME[$i]} at ${BASH_SOURCE[$((i+1))]} line ${BASH_LINENO[$((i+1))]}"
        done
        return $ret' ERR
  trap 'ret=$?; trap - ERR RETURN; return $ret' RETURN
  echo ok
  subroutine
  echo "By default, the ERR trap is not inherited"
  false
  echo "You won't see this"
}

main () {
  trapper
  echo "trapper returned status $?"
  false
  echo "still there"
}

main

Em zsh, você pode definir a função TRAPZERR em vez de definir uma interceptação para ERR (para compatibilidade) ou ZERR (em sistemas com um sinal chamado SIGERR - não sei de nenhum) . Mas se tudo que você quer fazer é retornar imediatamente (e não, por exemplo, imprimir uma mensagem de erro), é mais simples: basta definir a opção err_return . Opções são globais por padrão; defina a opção local_options para torná-los locais para a função de chamada (se a opção local_options for definida quando uma função retornar, as opções do horário em que a função foi chamada serão restauradas). Traps também são globais por padrão. Opções e armadilhas são herdadas em chamadas de função.

myfunction () {
  setopt local_options err_return
  false
  echo not executed
}
    
por 07.06.2015 / 00:46

Tags