Bash скрипт резервного копирования файлов
Обновлено: 07.07.2024
Резервное копирование — важная часть управления любой IT-инфраструктурой. Потребности в резервном копировании у всех разные, а хранение резервных копий в отдельном хранилище является хорошей практикой.
Есть много различных инструментов для работы с объектными хранилищами, например:
В данной инструкции приведен пример создания скрипта, который будет регулярно запускать консольный клиент, архивировать и переносить важные данные в объектное хранилище — Облачное хранилище.
Требования для выполнения примера
В качестве консольного клиента используем S3cmd с инструментом для автоматизации crontab.
Для начала работы потребуется:
- Облачный или выделенный сервер с установленной Ubuntu версии не ниже 18.04.
- Настроенный S3cmd.
- Пользователь в Облачном хранилище, созданный согласно инструкции Создание нового пользователя.
Создание скрипта для резервного копирования
В данной инструкции рассмотрим создание базового bash-скрипта, который создает резервную копию файла или каталога с помощью tar и далее загружает эту резервную копию в Облачное хранилище с помощью утилиты командной строки s3cmd.
Откройте на своем сервере домашнюю директорию:
С помощью редактора nano создайте пустой файл, например, с именем bkupscript:
Начните писать скрипт резервного копирования в текстовом редакторе с шебанга. Шебанг — это директива интерпретатора, которая позволяет запускать скрипты или файлы данных как команды и выглядит как последовательность из двух символов: решетки и восклицательного знака. Включая шебанг в начало скрипта, мы говорим оболочке запускать команды файла в bash.
Назначение переменных
Добавьте в скрипт переменные прямо под шебангом в верхней части текстового файла:
- DATETIME содержит метку времени, которую нужно прикрепить к имени полученного файла, чтобы каждый файл, резервная копия которого хранится в пространстве, имел уникальное имя. Эта временная метка создается путем вызова команды date и форматирования вывода для отображения двух последних цифр года (% y), двух цифр месяца (% m), двух цифр дня (% d), час (% H), минуты (% M) и секунды (% S);
- SRC — это исходный путь для файла или папки, в которую мы делаем резервную копию. $1 указывает, что мы берем это значение из первого параметра, переданного скрипту;
- DST — место назначения файла. В нашем случае это имя пространства, в которое мы загружаем резервную копию. Это имя будет получено из второго параметра, переданного в скрипт, как указано в $2;
- GIVENNAME — выбранное пользователем имя для файла назначения. Результирующее имя файла будет начинаться с GIVENNAME, и к нему будет добавлено DATETIME. Это имя происходит от третьего параметра, переданного скрипту $3.
Сбор файлов
Прежде чем скрипт сможет передавать что-либо в выбранное пространство, ему сначала необходимо собрать нужные файлы и объединить их в единый пакет, который мы можем загрузить. Это выполняется с помощью утилиты tar, условных операторов и функции tarandzip:
Когда вызывается инструкция if, скрипт выполняет команду tar и ожидает результата. Если команда выполнена успешно, будут выполнены строки после оператора then:
Часть else этого скрипта будет выполняться только в том случае, если команда tar обнаружит ошибку при выполнении:
Заканчивайте скрипт if/then/else фразой fi , что на языке bash означает, что предложение if закончилось.
Завершенная функция tarandzip будет выглядеть так:
Перенос файлов в объектное хранилище
Добавим в скрипт резервного копирования функцию передачи файла movetoSpace в выбранное пространство с помощью команды s3cmd. Используем s3cmd и переменные, которые мы объявили ранее, для создания команды, которая будет помещать файлы резервных копий в выбранное пространство:
- /bin/s3cmd вызывает s3cmd — инструмент командной строки, используемый для управления сегментами хранилища объектов;
- put используется s3cmd для загрузки данных в бакет;
- $ GIVENNAME- $ DATETIME.tar.gz — это имя резервной копии, которая будет загружена в пространство. Он состоит из четвертой и первой объявленных нами переменных, за которыми следует .tar.gz, и создается функцией tarandzip;
- s3: // $ DST ; — место, куда мы загружаем файл;
- s3: // — это схема типа URI, используемая для описания мест хранения объектов в сети, а $DST; — это третья переменная, которую мы объявили ранее.
Добавьте уведомления о том, что процесс переноса файлов начался:
Поскольку команда будет либо успешной, либо неудачной (это означает, что она либо загрузит файлы в выбранное пространство, либо нет), можно сообщить пользователям, сработала ли она, повторив одну из двух строк, содержащихся в if/then/else, например:
В целом функция movetoSpace должна выглядеть так:
Настройка управления потоком
Предполагая, что скрипт настроен правильно, он при запуске должен прочитать команду ввода, присвоить значения из нее каждой переменной, выполнить функцию tarandzip, а затем выполнить функцию movetoSpace.
Если сценарий завершится неудачно между любой из этих точек, он должен напечатать вывод нашей функции showhelp, чтобы помочь пользователям в устранении неполадок.
Мы можем упорядочить отлов ошибки, добавив в конец файла условную инструкцию if / then / else:
Первый оператор if в приведенном выше разделе проверяет, что третья переданная переменная не пуста. Это происходит следующим образом:
- [] — квадратные скобки означают, что то, что находится между ними, является тестом. В этом случае проверка заключается в том, чтобы конкретная переменная не была пустой;
- ! — в данном случае этот символ означает «нет»;
- -z — эта опция указывает на пустую строку и в сочетании с ! мы запрашиваем не пустую строку;
- $ GIVENNAME указывает, что строка, которая не должна быть пустой, является значением, присвоенным переменной $GIVENNAME. Этой переменной присваивается значение, переданное третьим параметром, при вызове скрипта из командной строки. Если мы передадим сценарию менее 3 параметров, в коде не будет третьего параметра для присвоения значения $GIVENNAME, он назначит пустую строку и этот запуск завершится ошибкой.
Пример скрипта
Завершенный скрипт выглядит следующим образом:
После проверки скрипта закройте файл сочетанием клавиш CTRL+Х и сохраните внесенные изменения клавишей Y+ENTER перед выходом из nano.
Автоматизация резервного копирования с помощью Crontab
Настройте задание cron, которое будет использовать скрипт для регулярного резервного копирования в выбранное пространство. В рамках этого примера резервное копирование будет выполняться каждую минуту.
Сделайте скрипт исполняемым:
Отредактируйте файл crontab, чтобы скрипт запускался каждую минуту:
При первом запуске команды crontab -e будет предложено выбрать редактор из списка:
Можно выбрать nano по умолчанию или любой другой текстовый редактор.
Перейдя в crontab, добавьте следующую строку внизу скрипта:
Закройте файл сочетанием клавиш CTRL+Х и сохраните внесенные изменения клавишей Y+ENTER.
Если оставить задание cron запущенным без каких-либо изменений, новый файл будет копироваться в выбранное пространство каждую минуту. Убедившись, что cron работает успешно, перенастройте crontab для резервного копирования файлов с нужным интервалом.
При проблемах с сайтом или хостингом администратор проекта должен иметь возможность быстро вернуть сайт в рабочее состояние. Для этих целей можно периодически создавать дубликат данных сайта: файлов и базы данных. Этот процесс называется резервным копированием, или бэкапом. При наличии бэкапа администратор сайта в любой момент вернёт работоспособность сломанного сайта или, в некоторых случаях, перенесет сайт на другой сервер.
Резервное копирование - процесс важный, но затратный по времени, если выполнять его вручную. Поэтому создание бекапа стараются автоматизировать, особенно, когда сайт часто обновляется и дубликат надо создавать ежедневно.
Многие хостинги предлагают собственный функционал для создания копии сайта и почти всегда за это взимается плата (за создание копии или за хранение копии на сервере). Но процесс резервного копирования можно сделать бесплатным и использовать только встроенные возможности сервера без стороннего программного обеспечения.
В этой статье будет написан скрипт для выполнения всей рутинной работы по резервному копированию.
Создадим файл с расширением «.sh», например «backup.sh» и в самом начале файла на первой строке напишем обязательную строку:
Чтобы этот скрипт можно было запустить, необходимо присвоить ему права на исполнение. Для этого на хостинге через файловой менеджер зайдите в свойства созданного файла backup.sh и установите соответствующие права на исполнение файла.
Если вам привычнее работать с консолью, то назначить нужные права через консоль можно командой chmod +x backup.sh . Для отображения консоли на хостингах обычно есть специальные инструменты, как «SSH-консоль», «Терминал» и т.п.
Конфигурация скрипта
Для удобства в самом начале файла создадим условный раздел со значениями будущих параметров. При изменении параметров или при использовании скрипта для другого проекта не нужно будет искать и менять в коде тот или иной параметр, достаточно будет поменять значение в разделе с конфигурацией.
Комментарии перед каждым параметром поясняют его предназначение. Остановимся лишь на некоторых строках.
VERSION - параметр определяет используемую версию ядра cms concrete5. Обратите внимание, что параметр VERSION сработает только для concrete5 версии выше 5.7.5.
DATE - если сайт обновляется редко, а бэкапы делаются раз в неделю, то параметр DATE имеет смысл сократить и не указывать аргументы для вывода часов и минут (%H и %M соответственно)
PROJECT_FILES - это путь до корня проекта, то есть папка, где среди прочих файлов лежит файл index.php.
DB_PASSWORD - не бойтесь держать здесь пароль базы данных, ниже в разделе «Безопасность» будут показаны действия, как запретить доступ к скрипту.
Комментарии в коде
Cоздание папки для бекапа
При запуске скрипта проверяем существование папки для бэкапов. При отсутствии папки - создадим её.
ключ -p позволяет создать вложенные папки.
Команда Echo
Основное предназначение команды echo - выводить текст в терминал. Но мы хотим записывать все операции в отдельный файл. К сожалению, факт успешного выполнения операции в файл не запишутся, но каждую операцию мы будем сопровождать командой echo с каким-то текстом. Именно это текст мы увидим в логах.
Создание архива файлов:
Для уменьшения размера архива мы исключаем папку с кешем сайта - эти файлы совершенно не нужны в резервной копии.
Ключ -r означает, что архивация должна пройти рекурсивно по всем подпапкам.
Ключ -x позволяет указать файлы и папки, которые будут исключены их архива
Ключ -q делает архивацию в тихом режиме, не выводя весь список архивируемых файлов.
Кроме того, архив можно сделать ещё меньше - исключите из архива папку с ядром системы «/concrete». Ядро для каждой версии cms перманентно и при необходимости вы всегда сможете скачать официальный дистрибутив с cms concrete5 и скопировать оттуда папку с ядром системы («/concrete»). Чтобы не ошибиться с номером версии cms - в имена архива и дампа базы мы включаем номер версии cms concrete5 («c5core-VERSION»)
Создание дампа базы данных
Прописываем команду для создания дампа базы:
Завершение скрипта
На последнем этапе проверим, что архив и дамп существуют. Если хотя бы один файл отсутствует - выводим ошибку. Для полноценного восстановления сайта требуются одновременно и архив, и дамп базы.
Запуск скрипта:
— Запуск вручную: введите в консоль «./backup.sh» и нажмите «Enter»
— Запуск + запись в лог: ./backup.sh | tee
— Запуск через cron: для этого на всех хостингах есть специальный раздел с настройкой CRON.
Безопасность
В начале скрипта в разделе с конфигурацией мы прописали полные данные для подключения к базе. Если всё оставить как есть, то это угрожает безопасности вашего сайта. Дополнительно выполним действия, чтобы злоумышленники не могли получить доступ к файлу.
- Переименуем наш файл: вместо backup.sh напишем случайный набор букв и цифр, например sdJiLA4Ui4Hjq.sh .
- В файле «.htaccess» запретим доступ к файлу. Для этого в файле «.htaccess» (создайте его, если он отсутствует) добавьте строки:
- Файл со скриптом можно держать не с файлами сайта, а положить в отдельную папку, недоступную извне.
Код скрипта
Объединим весь написанный код в одном месте.
От автора
Этот скрипт выполняет простую задачу: создаёт файлы, чтобы сломанный по каким-то причинам сайт можно было вернуть в рабочее состояние. Вы можете взять за основу этот bash-скрипт и дополнить его своим кодом под ваши потребности: настроить выгрузку копий на внешний FTP-сервер, удалять старые неактуальные копии. Для написания bash-скриптов в Интернете можно найти множество мануалов с готовыми кусками кода.
Иногда системным администраторам, программистам, web-дизайнерам и много кому ещё нужно запускать одни и те же команды или скрипт с некоторой периодичностью. Для таких целей используется специальная утилита Cron , встроенная во все дистрибутивы Unix. Пользоваться Cron’ом необычайно легко. Сейчас расскажу как.
Для начала создадим какой-нибудь простой bash-скрипт, например скрип резервного копирования и архивирования конфигурационных файлов, в моём случае конфигурационных файлов Apache2 и ftp-сервера.
mkdir / home / user / bash-scripts / backup
cp / etc / apache2 / apache2.conf / home / user / bash-scripts / backup / apache2.conf-backup
cp / etc / apache2 / sites-available / site / home / user / bash-scripts / backup / site-backup
cp / etc / proftpd / proftpd.conf / home / user / bash-scripts / backup / proftpd.conf-backup
tar cvvzf "/home/user/bash-scripts/backup-`date +%F-%X`.tar.gz" / home / user / bash-scripts / backup /
rm -r / home / user / bash-scripts / backup
Этот скрипт копирует конфигурационные файлы и архивирует их в папку, в названии которой присутствует дата и время сохранения. Назовём его ‘ backup-script ‘ а лежать он у нас будет в домашнем каталоге (/home/user/). Теперь нам надо чтобы этот скрипт запускался, ну допустим, каждые 10 минут. Для этого введём команду
Этой командой мы открываем для редактирования файл crontab для данного пользователя, в моём случае это user. Если нашему скрипту нужны права супер пользователя, то нужно редактировать crontab суперпользователя. Делается это командой
sudo crontab -u root -e
Ну и если заменить root а логин другого пользователя, мы будем редактировать его crontab .
Сразу напишу, чтобы посмотреть файл crontab введите команду.
Файл crontab имеет следующую структуру:
поле1 поле2 поле3 поле4 поле5 команда
Значения первых пяти полей:
1.минуты— число от 0 до 59
2.часы — число от 0 до 23
3.день месяца — число от 1 до 31
4.номер месяца в году — число от 1 до 12
5.день недели — число от 0 до 7 (0-Вс,1-Пн,2-Вт,3-Ср,4-Чт,5-Пт,6-Сб,7-Вс)
Все поля обязательны для заполнения. Не сложно догадаться что первые 5 отвечают за определения периодичности запуска команды, а последняя собственно команда или полный путь к скрипту. Таким образом, чтобы запустить наш скрипт резервного копирования раз в 10 минут надо вписать следующую строчку.
*/ 10 * * * * / home / user / backup-script
* - значит все возможные варианты, / служит для определения периодичности выполнения задания. Если нужно будет выполнять скрипт раз в 3 часа впишите в значения часы */3 а в минуты просто *, если раз в сутки — впишите */23 , ну почти сутки. Так же в одно поле можно вводить несколько значений через запятую, например если хотите выполнять скрипт 1ого, 5ого, и 25ог числа каждого месяца введите 1,5,25 вместо третей звёздочки. Ещё можно вводить промежуток времени, если ,допустим, в часы ввести 12-17 то скрипт будет выполняться с 12 до 17 включительно раз в час.
Ну вот и всё, в заключение пару примеров:
0 */ 3 * * 2,5 / home / user / backup-script
15 */ 3 * * * / home / user / backup-script
45 15 * * 1 / home / user / backup-script
13 13 13 * 5 / home / user / backup-script
30 00 * * 0 / home / user / backup-script
Резервное копирование должно быть таким, чтобы Вы в любой момент могли сменить хостера и переехать на новый сервер. Поэтому весь процесс создания архивов должен быть автоматизирован. А файлы бэкапов должны лежать в надежном месте с возможностью круглосуточного доступа из любой точки планеты.
Публикую очередное решение по резервному копированию вебсервера. Этот bash скрипт создает единый архив базы данных и всех файлов сайта. Для удобства на диске локально хранится 30 последних резервных копий. А для надежности архивы резервных копий выкладываются на облачное хранилище
Я так не люблю, раскрываешь архив, а там папка home, заходишь в нее, а там еще одна, ты в нее, за ней следующая и так далее, короче матрешка. Замучаешься до содержимого добираться.
Поэтому перед созданием архива выполним команду:
Подробнее о всех параметрах tar можно почитать в официальном мануале здесь.
Как создать резервную копию базы данных MySQL
Единый файл резервных копий сайта
Чтобы решение было изящным, объединим два архива файлов сайта и дампа базы данных в один архив. Только теперь уже без сжатия, так как каждый из них мы их предварительно пропустили через gzip.
Для удобства имя файла составим из имени используемого домена и времени создания.
Как сохранить резервную копию сайта в Яндекс.Диск
В качестве облачного хранилища совсем не обязательно должен выступать Microsoft SkyDrive или любой другой сервис, использующий для доступа протокол WebDAV.
Как убрать старые копии файлов, сохранив несколько последних
В конце скрипта уберем ненужные файлы, это архивы файлов и базы данных и ограничим количество архивный копий сайта.
Осуществим поиск устаревших резервных копий и при наличии таковых их удалим. За это отвечает нижеследующий код:
Запуск скрипта резервного копирования
Сохраняем скрипт, к примеру backup.sh. И присваиваем ему права на исполнение:
Удобнее всего использовать CRON для запуска скрипта по расписанию. Я создаю резервные копии раз в сутки в часы наименьшей нагрузки, то есть во второй половине ночи под утро.
Не забываем про владельцев папок и файлов, когда будем запускать скрипт на исполнение. Ведь файлы пользователя VASYA будут недоступны, если запустить скрипт от имени пользователя PETYA.
Результаты работы скрипта резервного копирования
Каждый день в 6 утра на сервере создается резервная копия сайта (файлы плюс база данных) и отправляется в облачное хранилище
Всегда рекомендуется делать резервные копии важных данных (документов, изображений, музыки и т. д.),
Резервная копия должна храниться на флэш-накопителе USB.
Но я также хотел сохранить удаленные файлы на пару дней, в случае случайного удаления файлов.
Есть много способов выполнить эту задачу, но я решил использовать для этой цели rsync и cronjob.
Оба инструмента делают процесс резервного копирования очень гибким.
Очень легко управлять временем процесса резервного копирования cronjobs, а rsync упрощает изменение адресата (например, другой папки, устройства или удаленного хоста).
Моя идея состояла в том, чтобы добавить cronjob, чтобы запустить скрипт bash, который использует rsync для копирования каталогов и файлов на флешку.
Но имена устройств флеш-накопителей меняются, если вы подключаете их в другом порядке.
Чтобы избежать этой проблемы, я добавил правило udev для создания символической ссылки каждый раз, когда флешка подключена.
Добавьте правило udev для создания символической ссылки
Прежде всего, нужно было выяснить имя устройства флеш-накопителя.
Поэтому я подключил его и посмотрел на разделы:
Эти две строки были наиболее интересными из результатов:
Но мне нужно было больше информации (идентификатор продавца, идентификатор продукта и серийный номер) флеш-накопителя, чтобы добавить правило udev. я использовал
чтобы получить подробную информацию обо всех устройствах USB, которые подключены.
Вот выдержка из вывода со всей необходимой мне информацией:
Правила udev находятся в /etc/udev/rules.d и имеют «специальное» имя файла.
Все правила udev обрабатываются в лексическом порядке, т. е. вы можете установить порядок правил udev с префиксом правила.
Содержимое файлов правил udev является ключевыми, парами значений, и для этой цели наиболее важными являются KERNEL и ATTR.
Значение KERNEL сопоставляется с именем устройства ядра, а значения ATTR сопоставляются с атрибутами устройства (я не хочу вдаваться в подробности).
Вам необходимо перезагрузить правила udev или перезапустить демон udev, чтобы «активировать» правило udev.
В моем случае (Slackware Linux) я использовал:
Теперь правило udev активируется и будет создавать символическую ссылку каждый раз, когда устройство будет подключено.
В Arch Linux вам не нужно перезагружать демон udev, он автоматически обнаруживает изменения.
Просто подключите USB-накопитель снова, и символическая ссылка должна быть доступна.
Скрипт резервного копирования
Следующий скрипт отражает данные каталоги в BACKUP_FOLDERS на флеш-накопитель, то есть если вы удалите файл в исходном каталоге, он также будет удален на флеш-накопителе, и восстановить эти файлы не удастся.
Это хороший вариант, поскольку зеркальная папка на флеш-накопителе будет обновлена, и все удаленные файлы будут сохранены в другом каталоге.
Я использовал переменную DELFILES для определения папки всех удаленных файлов.
Я также хотел знать, был ли процесс резервного копирования успешным или произошла ошибка.
Настройка задания cron
Читайте также: