Контекст:
У меня есть сценарий 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
и напишу rsync error: получен SIGINT, SIGTERM или SIGHUP (код 20) в rsync.c (544) [sender=3.0.6]
на экран, после чего скрипт просто умирает; без очистки, без отлова. Почему прерывание/уничтожение rsync
не вызывает ловушку?
Я пробовал использовать переключатель --no-detach
с rsync, но это ничего не изменило.
У меня bash 4.1.2, rsync 3.0.6, centOS 6.2.