Я создаю простое решение для резервного копирования базы данных для клиента, использующего веб-хостинг в DataFlame.
Учетная запись веб-хостинга предоставляет доступ к cron, но не к оболочке.
У меня есть сценарий резервного копирования базы данных, создающий регулярные резервные копии, и я хочу автоматически удалить те, которые были старше N дней.
Я пытался использовать
find -v $backup_dir -mtime +$keep_days -name "*db.tar.gz" -delete
однако пользователь, выполняющий сценарий, не имеет разрешения на запуск find
.
Можете ли вы подсказать, как это реализовать без использования find
команда?
Вот сокращенная версия сценария, который я использовал в конце, на основе ответа @cjc.
#!/bin/sh
# Script to backup ... database.
#
# A rolling backup is used. The size of period backed up is configurable.
# The period size is expressed in terms of an arbitary time unit "timeunit".
#
# Files are saved with format:
# <date>-...-<index within period>.sql.tar.gz
#
# Author: Calum J. Eadie
### Configuration
backup_dir=/home/..../backups
# The size of a timeunit. Eg. 300 for a timeunit that is 5 minutes long.
seconds_per_timeunit=$(expr 60 \* 60 \* 6) # 6 hours
# The size of backup period in timeunits.
keep_timeunits=$(expr 4 \* 30) # 30 days
### Script
# Form files names
date_string=`date +%Y-%m-%d-%H-%M-%S`
# Time since unix epoch in timeunits
epoch_timeunits=$(expr $(date +%s) / $seconds_per_timeunit)
# Index unique to timeperiod.
backup_index=$(expr $epoch_timeunits % $keep_timeunits)
raw=$backup_dir/$date_string-...-$backup_index.sql
compressed=$raw.tar.gz
# Remove old backup
rm -v $backup_dir/*-...-$backup_index.sql.tar.gz
# Create new backups
mysqldump -u ... -p... --databases ... --add-drop-database --add-drop-table > $raw
tar czf $compressed $raw
rm $raw
Одна из хакерских идей может заключаться в том, чтобы включить дни, прошедшие с эпохи (т.е. date +%s
разделить на 86400) на ваш $ keep_days в имя файла.
В этом случае вам не придется удалять старые файлы резервных копий. Вы бы просто перезаписали старые, как только снова появится число дней с начала по модулю $ keep_days.
Что-то вроде этого:
#!/bin/bash
keepdays=60
epochdays=$(expr $(date +%s) / 86400)
backupindx=$(expr $epochdays % $keepdays)
backupfile=/path/to/backup/file.${backupindx}.db.tgz
Итак, сегодня, 27 марта 2012 года, у вас будет файл резервной копии file.7.db.tgz, который будет перезаписан через 60 дней.
Вы сказали, что у вас нет доступа к оболочке. Предполагая, что вы имели в виду отсутствие интерактивного доступа к оболочке, этот сценарий Bash рекурсивно удаляет архивы db в течение 3 дней (рассчитывается путем взятия текущей даты и вычитания 3 дней в секундах и сравнения ее со временем модификации архива).
#!/bin/bash
for linkname; do
if [[ -d "$linkname" ]]; then
"$0" "$linkname"
elif [[ "$linkname" =~ '^.*db\.tar\.gz$' ]]; then
if (( $(stat --format=%y "$linkname") < ( $(date +%s) - 259200) )); then
rm -f "$linkname"
fi
fi
fi
Вы уверены, что у вас нет доступа к find
? Или это просто не на пути? Попробуйте запустить его как /usr/bin/find
посмотрим, работает ли это для вас.
Если это не сработает, вы в трудном положении. Если find
недоступен, и у вас нет доступа к оболочке, вы не знаете, что является доступный. Если бы Perl был доступен, это был бы довольно тривиальный Perl-скрипт для выполнения вышеуказанной задачи. Используя только оболочку. . . Я бы, наверное, попробовал что-то вроде этого:
ls -t /backup_dir/*.db.tar.gz | sed "1,5d" | xargs rm -f
куда 5 - это количество дней, которое вы хотите сохранить (при необходимости измените).
Краткое объяснение: ls -t
составляет список каталога, отсортированный по времени (сначала самые новые). В sed "1,5d"
говорит sed
чтобы удалить первые 5 строк из ввода (соответствующие нашим 5 новейшим файлам). В заключение, xargs
объединяет листинг и сообщает rm
удалить их.