anonymous
написал 13 марта 2006 года в 12:40 (731 просмотр)
Ведет себя
неопределенно; открыл 1814 темы в форуме, оставил 5575 комментариев на сайте.
Хочу наладить простое резервное копирование информации с помощью cron, tar и gunzip.
Создал скрипт, залил в крон, все нормально.
#!/bin/bash
tar -czf archivename.tar.gz /path/to/dir
Но мне нужно чтобы архив создавался за определенный период времени, например:
13.10.2006 — Создан архив от 13.10
14.10.2006 — Создан архив от 14.10
15.10.2006 — Создан архив от 15.10
16.10.2006 — Удален архив от 13.10; Создан архив от 16.10.
Логику написания данного скрипта понимаю, но познания shell достаточно скромные.
Если у кого-нибудь есть похожий скрипт, пожалуйста, приведите пример.
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1
ecobeing.ru
Экология и вегетарианство на благо всем живым существам Планеты.
а просто поместить твой скрипт:
в папку /etc/cron.hourly не проще?
правда, я не помню, будет ли cron как-то каждый новый файл называть по-новому
Создавать каждый раз новое имя файла — не проблема.
Я хочу получать не более трех файлов с архивами.
брррр…
не понял.
тебе надо, чтобы архивов (т.е. твоих бэкапов) было не более трех?
Именно.
Неболее трех (пяти, десяти, любое число).
Если делать просто архивирование, допустим ежедневное для mysql, то таких архивов будет 365 штук в году.
Мне же нужно только за последние три дня или неделю.
так. давай отделим мух от котлет. сколько бэкапов в день ты хочешь делать? или только раз в неделю, месяц? какова переодичность?
1. Периодичность — 1 бекап \ сутки
2. Хочу иметь 7 бекапов в неделю.
3. Хочу иметь бекапы только за неделю (7 дней).
получается так, что каждый день у тебя делается бэкап. в понедельник, вторник, …..
в воскреченье будет седьмой, а когда наступит очередной понедельник, ты хочешь, чтобы у тебя сделался бэкап, а сделанный в предыдущий понедельник удалился. так?
Именно так
вывод date давай
мда…
Я бытаюсь написать скрипт,
познания шелл программирования минимальные.
Думал уже что-то готовое есть.
Напишу — поделюсь.
у меня готового нет. для того, чтобы помочь тебе написать скрипт, нужна исходная информация, которую ты не всю предоставил.
давай вывод date, будет тебе скрипт;)
$date Пнд Мар 13 16:10:35 EET 2006
$date --help
Использование: date [КЛЮЧ]… [+ФОРМАТ]
или: date [-u|--utc|--universal] [ММДДччмм[[ВВ]ГГ][.сс]]
Выводит текущее время в заданном ФОРМАТЕ, или устанавливает системное время.
-d, --date=СТРОКА показать не текущее время, а время, описанное
заданной СТРОКОЙ
-f, --file=ФАЙЛ соответствует применению --date для каждой
строки ФАЙЛА
-IСПЕЦ, --iso-8601[=СПЕЦ] вывести дату/время в виде, соответствующем
стандарту ISO-8601.
СПЕЦ=`date' для получения только даты,
`hours’, `minutes' или `seconds' для получения
даты и времени с указанной точностью.
--iso-8601 без СПЕЦ эквивалентно `date’.
-r, --reference=FILE display the last modification time of FILE
-R, --rfc-2822 output RFC-2822 compliant date string
-s, --set=STRING set time described by STRING
-u, --utc, --universal print or set Coordinated Universal Time
--help показать эту справку и выйти
--version показать информацию о версии и выйти
ФОРМАТ управляет выводом. Единственный ключ, допустимый для второй
формы, задает координированное универсальное время. Воспринимаются
следующие последовательности:
%% знак %
%a местное сокращенное название дня недели (пон..вск)
%A местное полное название дня недели, переменной длины (понедельник..воскресенье)
%b местное сокращенное название месяца (янв..дек)
%B местное полное название месяца, переменной длины (январь..декабрь)
%c местное время и дата (Срд Фев 16 16:28:09 MSK 2000)
%C век (год, деленный на 100 и округленный до целого) [00-99]
%d день месяца (01..31)
%D дата (мм/дд/гг)
%e день месяца, пробелы вместо нулей ( 1..31)
%F эквивалентно %Y-%m-%d
%g двузначный год, соответствующий номеру недели %V
%G четырехзначный год, соответствующий номеру недели %V
%h то же, что и %b
%H час (00..23)
%I час (01..12)
%j номер дня в году (001..366)
%k час ( 0..23)
%l час ( 1..12)
%m месяц (01..12)
%M минуты (00..59)
%n новая строка
%N наносекунды (000000000..999999999)
%p местный индикатор AM или PM заглавными буквами (пусто во многих локалях)
%P местный индикатор AM или PM строчными буквами (пусто во многих локалях)
%r время, 12-часовой формат (чч:мм:сс [AP]M)
%R время, 24-часовой формат (чч:мм)
%s число секунд, истекших с `00:00:00 1970-01-01 UTC' (расширение GNU)
%S секунды (00..60); 60-ая нужна для високосной секунды
%t горизонтальная табуляция
%T время, 24-часовой формат (чч:мм:сс)
%u день недели (1..7); 1 обозначает понедельник
%U номер недели в году, если первый день недели — воскресенье (00..53)
%V номер недели в году, если первый день недели — понедельник (01..52)
%w день недели (0..6), 0 означает воскресенье
%W номер недели в году, если первый день недели — понедельник (00..53)
%x местное представление даты (дд/мм/гг)
%X местное представление времени (%H:%M:%S)
%y последние две цифры года (00..99)
%Y год (1970…)
%z RFC-2822 style numeric timezone (-0500) (a nonstandard extension)
%Z time zone (e.g., EDT), or nothing if no time zone is determinable
By default, date pads numeric fields with zeroes. GNU date recognizes
the following modifiers between `%' and a numeric directive.
`-' (hyphen) do not pad the field
`_' (underscore) pad the field with spaces
Об ошибках сообщайте по адресу .
пошевелить мозгами немного и поэкспериментировать с ключами у date.
может 'date +%d%m%y' будет что надо?
хотя для сортировки я бы наоборот расположил.. ;)
в общем, читать внимательно:
man date
man tar (как оному рассказать, что надо паковать только файлы позднее заданной (которую можно получить по команде date))
man gzip или bzip2 (впрочем, внимательное прочтение мана по tar про них упомянет)
и что ещё? описание по shell.
man bash
только это не учебник…
кроме того, есть opennet.ru/ — где много чего интересного есть по теме
тогда попробуй так: в /etc/cron.daily запихивай скрипт с таким содержанием:
#!/bin/sh
ls /path/to/dir |grep -v `date +%a%d%m%y`| grep `date +%a`| xargs rm -f
tar -czf «archiv`date +%a%d%m%y`».tar.gz /path/to/dir
Тут в первой строчке конструкция: «grep -v `date +%a%d%m%y`|» — всё-таки лишняя.
а я бы, сделал всё чуть проще…
А если уж заморачиваться с датами, то удобнее пользоваться find.
да, точно.
черт. файла, созданного в этот день, еще нет…
:(
а если подумать, то есть такая хрень, как logrotate, которая делает тоже самое, только несколько более удобно и стабильно ;)
Вот именно, что даже если и есть, то второй строчкой он всё равно будет создан заново. Поэтому удалить его перед повторным созданием не помешает ;).
Фига себе, проще.. ;)
Проще тогда уж действительно logrotate, как сказал Genie. Но откуда ж знать, есть ли он у автора темы, настроен ли…
Скрипт Эвила в этом плане универсальнее. С путями только быть повнимательнее ;). Потому как имя /path/to/dir после 'ls' НЕ должно быть равым имени каталога /path/to/dir, архив которого делается.
В данной задаче не удобней.
man tar читамши?
оно само умеет. ;)
Эм… find и tar, насколько я понял, это разные утилиты? И даже из разных пакетов, да? ;) Это хорошо, что tar умеет find (я, признаюсь, этого в man и вправду не нашёл. Хотя и не особо-то искал ;)) — универсальный всё-таки архиватор ;). Однако ни я, ни rgo про него ни словом не обмолвились.
Можно я ещё раз повторю:
rgo>> А если уж заморачиваться с датами, то удобнее пользоваться find
fly4life> В данной задаче не удобней.
Просто, если с find действительно удобней (хоть с помощью tar, хоть — отдельной утилиты), то надо бы пример, чтоб убедиться в этом. А пока я считаю, что не удобней.
ага. только если мы собираемся архивировать, то это будем делать tar-ои. так?
далее. tar умеет искать файлы, которые изменялись после определённой даты
и не надо для этого брать find. про это я и говорил ;)
Ах, ну ежели обо всяких инкрементальных бекапах речь вести… Только find, о котором говорил rgo и чему возразил я, тут совсем ни при чём.
насчёт find. Вот эта строчка, как я понял, должна удалить устаревшие бекапы:
Так? Точнее один файл недельной давности. Вот как это делается с find:
…
Или нет, чего-то я на неё повнимательнее посмотрел — теперь вообще нифига не понимаю.
Но если всё-таки имелось в виду удалить бекап 7-ми дневной давности (и случайно оставшиеся с доисторических времён), то:
Единственная проблема — если предположить что последующая tar -zcf работает мгновенно, то будет вероятность оставить архивы за 8 дней, но это ведь вряд ли и не страшно, т.к. назавтра всё исправим.
этого заявления я просто не понял: как «/path/to/dir» может быть не равным «/path/to/dir», пускай и даже после 'ls’.
На всякий случай поясню, не знаю что, но поясню, мой скрипт будет создавать/удалять/переименовывать архивы в текущей директории, а /path/to/dir с ней соотностится только в том, что не стоит архивы хранить в дереве /path/to/dir.
А насчёт logrotate — так с него идею и содрал.
это я немного не то сказал. Суть в том, что с датами всё-таки придётся повозиться отдельно. Или иметь с некоторой вероятностью 7 или 8 архивов.
Часть этой строчки всё-таки лишняя (я писал выше, какая именно), но не суть..
В этой строке удаляется архив, в имени которого присутствует название текущего дня недели (параметр %a у date). Так что это не совсем «файл недельной давности». Т.е., он, конечно же, будет недельной давности, но только при соблюдении условия, что cron отрабатывал строго каждый день.
При таком правиле, если твой скрипт выполнится после, например, двухнедельного простоя машины (или cron’а), то он удалит все бекапы.
Если даже и мгновенно, то всяко после выполнения первой команды (в которой делается rm). Так что тут волноваться нечего ;).
Так всё просто ж ;). Вот смотри. Приведу для наглядности скрипт Эвила (в его первой строчке я удалил ненужную конструкцию, о которой говорил в поправке к скрипту):
В первой строке делается листинг директории с готовыми архивами. Во-второй указана директория, архив которой делается. Они не должны быть равными. Т.е. следовало бы в скрипте написать так:
Теперь по понятней? ;)
Я именно про это <font size=«-2»><font color=«grey»>[не стоит архивы хранить в дереве /path/to/dir]</font></font> и говорил ;). А говоришь, что не понял ;). А что делает твой скрипт — всем и так ясно. Догадались же, что на logrotate похоже ;)
;)
ага.
угу, это есть баг. :(
Но теперь если отлистнуть на страницу назад и посмотреть что же собственно было надо, то выясниться что число 7, бралось для примера. На самом деле может быть надо 3 или 9, автор топика ещё не решил.
А против этого будут возражения:
?
ахха. :))
1) найдётся ещё какой чукча, что файлы бакапа с «.» именовать додумается.. :)
2) может так:
count=`ls -A shell*pattern | wc -l`
if ((n>6)); then
ls -Atr shell*pattern | tail -n $((n-7)) | xargs -r rm -f
fi
3) однако, и тут для чукчи есть где разгуляться: пробел в имени и…
как не решил?
он в самом начале написал, что
У меня есть, только для бэкапа mysql баз. И удаляются базы за прошлый месяц, а не за неделю. Так что подправишь то, что нужно :)
угу. так приятнее. про wc я как-то забыл.
ну, если мы расчитываем на чукчу, засовывающего всё что ни попадя с форумов в cron, не разбираясь, что собственно и как делается… То я думаю следует срочно изменить линию поведения и в один голос твердить что logrotate это его главный инструмент, а man logrotate гораздо круче форума.
Но я тут, на досуге придумал другую штуку:
N — это количество живых архивов