Pull to refresh

Comments 28

Если надо просто удалить файлы, например, старее одной недели по маске, то можно с помощью find сделать что-то типа такого:

find /tmp/backup/ -name "files*.tar" -type f -mtime +7d -exec rm -f {} \;

Надо только настроить под себя, что бы полный бекап не прибить случайно.

а есть вариант «в одну строчку» удалить все старее чем Х единиц времени, но оставить один файл?
т.е. вот создаю я бэкапы и удаляю старые
потом случилось что то и бэкапы перестали по какой то причине создаваться, а удаление старых продолжается, и чтобы не потерять самый последний из имеющихся бэкапов его бы здорово оставлять в таких случаях…

Если оставаться на "find", то можно сделать "touch" на те файлы, которые не надо удалять перед самой командой удаления или что-то типа такого.

Или переименовывать что бы можно было по маске отфильтровать только то, что нужно.

т.е. задача сводится к тому, что перед удалением надо посмотреть какие файлы попадают под удаление, проанализировать что можно удалять и потом только удалить…

я прошиваю потому что как и многие писал свои скрипты бэкапа и вот именно такую задачу и решал, получилась хоть и небольшая но простынька кода на баше чтобы эту ситуацию проверять, вот и интересно есть ли иные варианты…

Можно и так, конечно. Но я имел ввиду немного другое: в процессе работы скрипта должно быть достаточно проверок, что бы понять что backup слопал северный пушной зверёк и вовремя остановиться.

То есть, при проблеме сохранения нет смысла делать чистку вообще.

P.S.: Я такие задачи обычно решаю не шел-скриптами, а python'ом. Там проще в плане перехвата ошибок и анализа. Но это уже отступление от задачи, конечно.

А что в вашем понимании «в одну строчку»?
Цикл и в одну строчку записать можно.

С другой стороны, если вы себе сами придумали формат названия бэкапов, что вам мешает тем же find получить список всех, и дальше через пайпу первый из списка удалить (например с помощью sed), остальные стереть. Если будет пусто — понятное дело ничего не сотрётся а первый сохранён будет.

Вариантов как это сделать — масса.

ага, только может произойти ситуация при которой скрипт бекапа по какой-то причине перестанет работать и вы этого не заметите, но вот скрипт с удалением работать не перестанет и удалит все)

"Замечать" -- это задача бекап скрипта. Если там ошибка, то до "find" вообще не должно доходить.

трамвай из буханки.жпг

Для таких дел есть уже более толковые тулзы с шифрованием, сжатием, дедупликацией и прочими плюшками и финтифлюшками. - restic, borg

Для таких дел есть уже более толковые тулзы с шифрованием, сжатием,
дедупликацией и прочими плюшками и финтифлюшками. - 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">
Очень странный скрипт получился. Сейчас перепроверьте пожалуйста

Спасибо!

Так намного лучше!

Пока так:
gpg: devpew: пропущено: Нет открытого ключа
gpg: encryption of '/tmp/backup/202205/202205191946.tar.gz' failed: Нет открытого ключа

С ключами разобраться моя проблема.

Мой скрипт, с помощью которого я делаю бэкапы в Linux

backup скрипт на bash без -eux - да вы просто смельчак

rm -rf ${ARCHIVES_DIR}${MNOW}/*.tar.gz

и в один прекрасный момент у вас переменные ARCHIVES_DIR/MNOW окажутся неопределенными и команда превратится в

rm -rf /*.tar.gz

со всеми вытекающими

Спасибо за подсказку. А set -eux надо в самом начале файла со скриптом ставить? или он в .zshrc устанавливается?

#!/bin/bash -eux

минимальный джентльменский набор. Можно еще добавить set -o pipefail

devpew
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 в облаке.

ИМХО.

*пошёл сносить bareos и заливать везде скрипт ТСа

Эт правильно) сложно придумать что-то более сложное чем Bareos. Хотя для чего-то сложного возможно оно нужно

Жаль, что если вручную самому запускать инкрементальный бекап, но нужно сохранять все получившиеся файлы.
А не так как с обычным, захотел, удалил.

Сам отвечу.
Есть дифференциальные бекапы, которые основываются все время на полном.
Но с tar это не выйдет с разбегу.
Для этого нужно хранить самый первый snar файл и подсовывать его.

Sign up to leave a comment.

Articles