Как запустить команду до выхода из сценария Bash?

119

Если сценарий Bash имеет set -e, и команда в сценарии возвращает ошибку, как я могу выполнить некоторую очистку перед выходом из сценария?

Например:

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

Как я могу убедиться, что /tmp/fooон удален, даже если одна из команд ... do stuff ...не работает?

Дэвид Волевер
источник

Ответы:

194

Вот пример использования ловушки:

#!/bin/bash -e

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

trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

Вывод:

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

Обратите внимание, что даже несмотря на сбой строки asdffdsa, очистка все равно была выполнена.

devguydavid
источник
11

На bashстранице руководства (о встроенных функциях):

trap [-lp] [[arg] sigspec ...]
Команда arg должна быть прочитана и выполнена, когда оболочка получит сигнал (s) sigspec.

Итак, как указано в ответе Anon. , Вызовите в trapначале сценария, чтобы настроить желаемый обработчик для ERR.

dmckee --- котенок экс-модератора
источник
Беги help trapпосмотреть справку по встроенному.
Flimm
8

Из ссылки на set:

-e

Немедленно завершите работу, если простая команда (см. Раздел 3.2.1 Простые команды) завершается с ненулевым статусом, кроме случаев, когда команда, которая завершилась ошибкой, не является частью цикла до или пока, частью оператора if, частью && или || list, или если статус возврата команды инвертируется с помощью!. Прерывание ERR, если оно установлено, выполняется до выхода из оболочки.

(Акцент мой).

Anon.
источник
Возможно, стоит добавить «-E» при использовании «-e», см. Vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail
Макс Барраклаф
3

shверсия ответа девгуидавида .

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

ссылка: shellscript.sh

Saftever
источник
POSIXзаставляет меня улыбаться. :) Отличный обучающий сайт, на который вы тоже ссылались.
Cometsong