Комментарии 28
т.е. вот создаю я бэкапы и удаляю старые
потом случилось что то и бэкапы перестали по какой то причине создаваться, а удаление старых продолжается, и чтобы не потерять самый последний из имеющихся бэкапов его бы здорово оставлять в таких случаях…
Если оставаться на "find", то можно сделать "touch" на те файлы, которые не надо удалять перед самой командой удаления или что-то типа такого.
Или переименовывать что бы можно было по маске отфильтровать только то, что нужно.
я прошиваю потому что как и многие писал свои скрипты бэкапа и вот именно такую задачу и решал, получилась хоть и небольшая но простынька кода на баше чтобы эту ситуацию проверять, вот и интересно есть ли иные варианты…
Можно и так, конечно. Но я имел ввиду немного другое: в процессе работы скрипта должно быть достаточно проверок, что бы понять что backup слопал северный пушной зверёк и вовремя остановиться.
То есть, при проблеме сохранения нет смысла делать чистку вообще.
P.S.: Я такие задачи обычно решаю не шел-скриптами, а python'ом. Там проще в плане перехвата ошибок и анализа. Но это уже отступление от задачи, конечно.
Цикл и в одну строчку записать можно.
С другой стороны, если вы себе сами придумали формат названия бэкапов, что вам мешает тем же find получить список всех, и дальше через пайпу первый из списка удалить (например с помощью sed), остальные стереть. Если будет пусто — понятное дело ничего не сотрётся а первый сохранён будет.
Вариантов как это сделать — масса.
ага, только может произойти ситуация при которой скрипт бекапа по какой-то причине перестанет работать и вы этого не заметите, но вот скрипт с удалением работать не перестанет и удалит все)
трамвай из буханки.жпг
Для таких дел есть уже более толковые тулзы с шифрованием, сжатием, дедупликацией и прочими плюшками и финтифлюшками. - restic, borg
Кроме того, ничего не будет работать, если вы поставите слэш в конце.
Я бы сказал просто, что пути к файлам и каталогам должны быть без завершающего слэша (без "/").
Я их никогда там не ставлю и поэтому у меня такого вопроса не возникает.
./backup.sh: строка 7: +%a: команда не найдена
./backup.sh: строка 8: +%d: команда не найдена
./backup.sh: строка 9: +%d%b: команда не найдена
./backup.sh: строка 10: синтаксическая ошибка в условном выражении
./backup.sh: строка 12: синтаксическая ошибка рядом с «"»
./backup.sh: строка 12: `mkdir " class="formula inline">{MNOW}'
Добрый день! В статье с форматированием произошла катастрофа
Везде ARCHIVE_DIR заменилось на " class="formula inline">
Очень странный скрипт получился. Сейчас перепроверьте пожалуйста
Мой скрипт, с помощью которого я делаю бэкапы в Linux
backup скрипт на bash без -eux - да вы просто смельчак
rm -rf ${ARCHIVES_DIR}${MNOW}/*.tar.gz
и в один прекрасный момент у вас переменные ARCHIVES_DIR/MNOW окажутся неопределенными и команда превратится в
rm -rf /*.tar.gz
со всеми вытекающими
if [[ ! -d ${ARCHIVES_DIR}${MNOW} ]]
then
mkdir ${ARCHIVES_DIR}${MNOW}
else
echo &>/dev/null
fi
Зачем вот эта вся конструкция?
Как я её читаю — если нет директории с определённым названием, создай директорию, в противном случае пошли пустое эхо в нуль. Вы это зачем делаете? Чтобы получить нулевой код на случай если директория уже есть? Так у вас в скрипте нету проверки ненулевых значений `set -e` и скрипт всёравно не остановится.
Хотели избежать выписывания «File exists» когда директория уже присутствует? Можно перенавравить это самое сообщение в нуль.
mkdir ${ARCHIVES_DIR}${MNOW} 2>/dev/null
Но тогда у вас ненулевой код будет после mkdir, так? Но как я написал выше — вы и так с этим ничего не делаете.
Лучше всего будет просто сделать вот так:
mkdir -p ${ARCHIVES_DIR}${MNOW}
И всё. `man mkdir` обьяснит почему.
Дальше
if [ $(ls -d ${ARCHIVES_DIR}${MNOW}/*.tar.gz 2> /dev/null | wc -l) != "0" ]
then
gpg -r $EMAIL --encrypt-files ${ARCHIVES_DIR}${MNOW}/*.tar.gz \
&& rm -rf ${ARCHIVES_DIR}${MNOW}/*.tar.gz
fi
Вы выполняете листинг файлов, перенаправляете сообщение об ошибке что таких файлов нет в нуль, а потом считаете строки. Но ведь сообщение об ошибке, что таких файлов нет само по себе означает что их нет и считать ничего не надо, разьве не так?
Переделываем:
ls -d ${ARCHIVES_DIR}${MNOW}/*.tar.gz 2> /dev/null \
&& gpg -r $EMAIL --encrypt-files ${ARCHIVES_DIR}${MNOW}/*.tar.gz \
&& rm -rf ${ARCHIVES_DIR}${MNOW}/*.tar.gz
Ну а прочтение мануала gpg для того чтобы узнать как себя он поведёт если получит пустой список на входе `--encrypt-files` (и соответственно требуется-ли вообще проверять существуют-ли файлы) я оставлю в качестве разминки для мозгов
Денис, спасибо большое. Тот случай когда решил поделиться чем-то на хабре, но сам получил пользу
Единственное, что не понял про вот эту часть "Ну а прочтение мануала gpg для того чтобы узнать как себя он поведёт если получит пустой список на входе --encrypt-files
(и соответственно требуется-ли вообще проверять существуют-ли файлы) я оставлю в качестве разминки для мозгов"
В моем варианте мы ведь как раз проверяем, что файл должен быть
if [ $(ls -d ${ARCHIVES_DIR}${MNOW}/*.tar.gz 2> /dev/null | wc -l) != "0" ]
Если флаг `--encrypt-files` получит на входе пустой список — gpg не сработает.
Будет выписано сообщение об ошибке и завершена работа с ненулевым кодом. Так как у вас `rm` вызывается по цепочке через `&&`, срабатывать оно будет только если `gpg` вернёт нулевой код (отработает как надо)
Поэтому вполне достаточно:
gpg -r $EMAIL --encrypt-files ${ARCHIVES_DIR}${MNOW}/*.tar.gz \
&& rm -rf ${ARCHIVES_DIR}${MNOW}/*.tar.gz
Можно ещё при желании «зактнуть» gpg отправкой сообщения об ошибке в нуль или файл по желанию.
Ну и как указали в другой ветке, файлы стирать с флагом `-r` лучше не надо, отсюда
gpg -r $EMAIL --encrypt-files ${ARCHIVES_DIR}${MNOW}/*.tar.gz 2>/dev/null \
&& rm -f ${ARCHIVES_DIR}${MNOW}/*.tar.gz
Я давно *.gz забыл в пользу *.xz. И польза весьма большая, как по времени создания, а уже по времени извлечения - огромная. И по размеру полученному в результате.
Для продакшена без UI с возможность выбора на уровне файла - не гуд.
Для дома - инкрементный бэкап при современных объемах носителей - мазохизм.
tar(если нужно сохранить chown/chmod), p7zip(сложный пароль), davfs в облаке.
ИМХО.
Есть backup-manager (https://github.com/sukria/Backup-Manager) -- в Debian уже в пакетах идет. Все основные действия из статьи умеет делать сам.
*пошёл сносить bareos и заливать везде скрипт ТСа
Жаль, что если вручную самому запускать инкрементальный бекап, но нужно сохранять все получившиеся файлы.
А не так как с обычным, захотел, удалил.
Простые инкрементальные бэкапы в Linux с помощью TAR и GPG