Você encontrará estas duas técnicas de programação de shell úteis:
- Se você executar
set -e
, o shell será encerrado imediatamente se um comando retornar um status diferente de zero (exceto nos casos em que isso obviamente significa, como if
ou while
condicionais).
- Se você executar
trap 'somecode' EXIT
, então, se o script sair (seja explicitamente ou implicitamente por causa de set -e
), somecode
é executado primeiro. Na entrada em somecode
, $?
contém o status do último comando.
Assim, você pode escrever algo como
(set -e; trap 'abort operation a' EXIT; perform operation a; )
No bash, você pode definir um trap em ERR
em vez de EXIT
; tais traps são executados somente se o shell sair devido a set -e
. Além disso, ERR
traps são locais para funções.
set -e
operation_a () {
trap 'abort code' ERR
perform operation a
}
Quando você puder, é mais fácil preparar primeiro um rascunho e, em seguida, executar uma operação atômica para confirmar sua transação. Por exemplo, se você estiver gravando em um arquivo, grave em um arquivo temporário no diretório de destino e, em seguida, chame mv
para colocar o novo arquivo no lugar. Isso é muito mais robusto do que qualquer coisa que exija limpeza na forma de código de reversão, porque a reversão não será executada se o script morrer devido a uma kill -9
ou falta de energia.