Назад | Перейти на главную страницу

Команда `find` недоступна на веб-хосте, как реализовать удаление на основе времени модификации с помощью других команд?

Я создаю простое решение для резервного копирования базы данных для клиента, использующего веб-хостинг в 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 удалить их.