Контекст:
У меня есть bash-скрипт, который содержит подоболочку и ловушку для псевдосигнала EXIT, и он неправильно перехватывает прерывания во время rsync
. Вот пример:
#!/bin/bash
logfile=/path/to/file;
directory1=/path/to/dir
directory2=/path/to/dir
cleanup () {
echo "Cleaning up!"
#do stuff
trap - EXIT
}
trap '{
(cleanup;) | 2>&1 tee -a $logfile
}' EXIT
(
#main script logic, including the following lines:
(exec sleep 10;);
(exec rsync --progress -av --delete $directory1 /var/tmp/$directory2;);
) | 2>&1 tee -a $logfile
trap - EXIT #just in case cleanup isn't called for some reason
Идея сценария такова: большая часть важной логики выполняется в подоболочке, которая передается по каналу tee
и в лог-файл, поэтому мне не нужно tee
каждую строку основной логики получить все это в журнале. Всякий раз, когда подоболочка заканчивается или сценарий останавливается по какой-либо причине (псевдосигнал EXIT должен охватывать все эти случаи), ловушка перехватит ее и запустит функцию cleanup()
, а затем удалит ловушку. Команды rsync
и sleep
(спящий режим - всего лишь пример) запускаются через exec
, чтобы предотвратить создание процессов-зомби, если я убиваю родительский скрипт во время их выполнения, и каждую потенциально длительную команду обернут в свою собственную подоболочку, поэтому, когда exec
завершится, он не завершит весь сценарий.
Проблема:
Если я прерываю сценарий (через kill
или CTRL + C) во время выполнения команды exec / subshell wrapped sleep
, ловушка работает правильно, и я вижу сообщение "Очистка!" повторил и вошел. Если я прерываю сценарий во время команды rsync
, я вижу rsync
end и записываю rsync error: received SIGINT, SIGTERM, or SIGHUP (code 20) at rsync.c(544) [sender=3.0.6]
на экран, а затем сценарий просто умирает; без очистки, без ловушек. Почему прерывание / убийство rsync
не вызывает ловушку?
Я пытался использовать переключатель --no-detach
с rsync, но это ничего не изменило.
У меня bash 4.1.2, rsync 3.0.6, centOS 6.2.