Como executar um comando antes que um script Bash saia?

119

Se um script Bash possui set -ee um comando no script retorna um erro, como posso fazer uma limpeza antes da saída do script?

Por exemplo:

#!/bin/bash
set -e
mkdir /tmp/foo
# ... do stuff ...
rm -r /tmp/foo

Como garantir que a /tmp/fooremoção seja removida, mesmo se um dos comandos no ... do stuff ...falhar?

David Wolever
fonte

Respostas:

193

Aqui está um exemplo do uso de trap:

#!/bin/bash -e

function cleanup {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}

trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

Resultado:

dbrown@luxury:~ $ sh traptest
t: line 9: asdffdsa: command not found
Removing /tmp/foo
dbrown@luxury:~ $

Observe que, embora a linha asdffdsa falhe, a limpeza ainda foi executada.

devguydavid
fonte
11

Na página de bashmanual (relativa aos componentes internos):

trap [-lp] [[arg] sigspec ...]
O comando arg deve ser lido e executado quando o shell receber sinal (es) sigspec.

Portanto, conforme indicado na resposta da Anon. , Ligue trapno início do script para configurar o manipulador que você deseja no ERR.

dmckee --- gatinho ex-moderador
fonte
Corra help trappara ver alguma ajuda no built-in.
Flimm 27/02
8

Da referência para set:

-e

Saia imediatamente se um comando simples (consulte a seção 3.2.1 Comandos simples) sair com um status diferente de zero, a menos que o comando que falhe faça parte de um loop while ou while, parte de uma instrução if, parte de um && ou || lista ou se o status de retorno do comando estiver sendo invertido usando! Uma interceptação no ERR, se definida, é executada antes da saída do shell.

(Ênfase minha).

Anon.
fonte
Pode valer a pena adicionar "-E" ao usar "-e", consulte vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail
Max Barraclough
3

shversão da resposta de devguydavid .

#!/bin/sh
set -e
cleanup() {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}
trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

ref: shellscript.sh

Saftever
fonte
POSIXMe faz sorrir. :) Ótimo site de ensino ao qual você também se vinculou.
Cometsong