Manipulação de armadilhas e sub-inscrições implícitas em scripts de shell

8

Digamos que você tenha um script de shell que execute algum tipo de código de limpeza através de uma armadilha EXIT , como esta:

#!/bin/bash

mytrap () {
  echo "It's a trap!" >&2
}

trap mytrap exit

echo I am at the end of the script.

Isso, como esperado, imprimirá It's a trap! quando o script saídas:

$ sh myscript
I am at the end of the script.
It's a trap!

Você modifica o script para adicionar uma função que gera alguns saída que finalmente fica canalizada para outro comando, como este:

#!/bin/bash

mytrap () {
  echo "It's a trap!" >&2
}

myfunc () {
  echo "I've got a bad feeling about this..."
}

trap mytrap exit

myfunc | cat > /dev/null

echo I am at the end of the script.

Por causa do pipe, o código em myfunc é executado em um subshell ... e as subshells não parecem herdar o comportamento trap do pai, o que significa que se você executar alguma ação aqui que deve ser limpa pelo seu código de armadilha que não acontecerá.

Então você tenta isso:

myfunc () {
  trap mytrap EXIT
  echo "I've got a bad feeling about this..."
}

E ainda não dispara mytrap quando a sub-ssh sai. isto Acontece que você precisa de um exit explícito, como este:

myfunc () {
  trap mytrap EXIT
  echo "I've got a bad feeling about this..."
  exit
}

Com o código acima, mytrap será acionado apropriadamente após a saída do subshell:

$ sh myscript 
It's a trap!
I am at the end of the script.
It's a trap!

Esse comportamento é esperado? Fiquei surpreso com várias coisas aqui:

  • trap configurações não foram herdadas por subpainhas
  • A saída implícita
  • de um subshell não parece acionar um EXIT armadilha
por larsks 18.10.2015 / 16:25

1 resposta

5

O bash trap builtin permite a palavra-chave RETURN . Daí a mudança:

trap mytrap EXIT

para:

trap mytrap RETURN

Veja a discussão sobre trap em shell-builtins

    
por 18.10.2015 / 17:38

Tags