Перехват сигнала Bash, не обнаруживающий переменные, изменился после объявления блока 'trap' - PullRequest
9 голосов
/ 10 февраля 2012

У меня есть набор универсального кода очистки, который необходимо выполнять при выходе из определенного сценария bash, независимо от того, был ли он завершен нормально или был прерван. Я решил использовать псевдосигнал trap "..." EXIT для достижения этой цели.

В дополнение к общей очистке, есть еще одна особая очистка, которая должна выполняться только при нормальном завершении сценария. Я подумал, что могу вызвать это, проверив переменную блока «trap», например:

#!/bin/bash
done=false;
trap "{        
           #generic cleanup code goes here.
           if $done
           then
               #cleanup to be done only on completion goes here.
               echo Test;
           fi
       }" EXIT
#main script goes here
done=true;

Однако это не работает. Запуск следующего кода никогда не будет повторять «Test». Добавление явного exit вызова после done=true; ничего не меняет. Чего мне не хватает?

Ура!

1 Ответ

17 голосов
/ 10 февраля 2012

Ловушка интерполируется и использует значение $ done во время определения ловушки, а не при ее выполнении.Вы можете использовать одинарные кавычки вокруг определения ловушки или определить функцию.Определение функции, вероятно, чище:

#!/bin/sh
done=false
cleanup() { if $done; then echo Test; fi; }
trap cleanup EXIT
done=true

Это работает, потому что расширение переменных в функции откладывается до вызова функции, а не когда функция определена.

...