Скрипт для бэкапа linux сервера

bash: Бэкап без лишнего ПО

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

Задача: Бэкап данных в локальную директорию и на отдельный сервер, с использованием минимума стороннего ПО, логированием и оповещением администратора в jabber при сбоях. Все основные функции большинства ПО для автоматического бэкапа, но без установки оного, а следовательно без его багов (что, собственно, и привело к подобной идее).

А теперь к делу.

Для начала создадим и откроем скрипт

Объявим некоторые переменные.
TN — TASKNAME — имя задания.Используется для вывода в лог и определения названия файла.
Так как заданий несколько (ежемесячное, еженедельное, ежедневное) и писать на каждый случай скрипт было лень, я создал универсальный, в котором надо просто раскомментить нужные строки. Наименование заданий писать надо без пробелов, желательно в латинице, если не хотите проблем с кодировкой и неправильными параметрами команд.

TN=docs-monthly 
#TN=docs-weekly
#TN=docs-daily

Объявляем переменную с путем к файлу лога, и далее все сообщения об ошибках и остальном будем выводить в лог.

echo >>$LOGFILE echo "==================================================== $(date +'%d-%b-%Y %R')" >>$LOGFILE echo "Задание \"$TN\" запущено. " >>$LOGFILE

Есть проблема в том что если указывать в параметрах команд (напр. tar) имена каталогов с пробелами, скрипт срабатывает с ошибкой. Решение найдено на просторах интернета — операционная система linux использует пробел в качестве стандартного разделителя параметров команды. Переопределим стандартный разделитель (хранится в переменной $IFS) отличным от пробела, например \n – знаком переноса строки.
Запоминаем старое значение стандартного разделителя

SRCD — SouRCe Directory — каталог с данными для бэкапа
Теперь можно перечислять несколько каталогов, разделителем будет перенос строк как мы сами указали строкой выше

SRCD="/mnt/source/folder_1 /mnt/source/folder_2 /mnt/source/folder_N"

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

tar -czf $TGTD$OF $SRCD &>>$LOGFILE
tar -u -f $TGTD$OF $SRCD &>>$LOGFILE

Во втором случае лучше вместо $OF использовать конктретное имя файла потому что у меня например ежедневно апдэйтится еженедельный архив, а их $TN (имена задания) не совпадают, соответственно и $OF.

Читайте также:  Linux list only files

В переменной «?» ханится статус выполнения последней команды. Сохраним его, чтобы воспользоваться позже.

Теперь добавим условие — если процесс упаковки в архив tar закончился с ошибкой, отправляем сообщение админу, удаляем неудачный файл бекапа. Иначе продолжаем дальше — монтируем сетевую шару и кидаем в нее копию архива. После каждой операции проверяем результат выполнения, пишем логи, и либо продолжаем, либо извещаем админа и прерываем процедуру.

if [[ $STATUS != 0 ]]; then rm $TGTD$OF &>>$LOGFILE echo "###########################################" >>$LOGFILE echo "### Произошла ошибка! Бэкап не удался. ###" >>$LOGFILE echo "###########################################" >>$LOGFILE echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не создан" | sendxmpp -t -f /usr/local/etc/XMPP_settings логин_получателя@домен &>>$LOGFILE else echo "Файл бэкапа сохранен как \"$TGTD$OF\"" >>$LOGFILE echo "Бэкап успешно завершен в $(date +'%R %d-%b-%Y')!" >>$LOGFILE echo "Монтирование файловой системы для резервного архива $TGTD_archive" >>$LOGFILE mount $TGTD2 &>>$LOGFILE if [[ $? != 0 ]]; then echo "#############################################################" >>$LOGFILE echo "### Произошла ошибка при монтировании резервного ресурса ###" >>$LOGFILE echo "#############################################################" >>$LOGFILE echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не скопирован на резервный ресурс" | sendxmpp -t -f /usr/local/etc/XMPP_settings логин_получателя@домен &>>$LOGFILE exit fi echo "Начато копирование файла на резервный ресурс" >>$LOGFILE cp -f $TGTD$OF $TGTD_archive$OF &>>$LOGFILE if [[ $? != 0 ]]; then echo "#############################################################" >>$LOGFILE echo "### Произошла ошибка при копировании на резервный ресурс ###" >>$LOGFILE echo "#############################################################" >>$LOGFILE echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не скопирован на резервный ресурс" | sendxmpp -t -f /usr/local/etc/XMPP_settings логин_получателя@домен &>>$LOGFILE else echo "Копирование файла успешно завершено в $(date +'%R %d-%b-%Y')!" >>$LOGFILE echo "Файл скопирован как \"$TGTD_archive$OF\"" >>$LOGFILE fi echo "Размонтирование файловой системы для резервного архива $TGTD_archive" >>$LOGFILE umount $TGTD2 &>>$LOGFILE echo "Все операции завершены успешно!" >>$LOGFILE fi exit

В процессе мы копируем архив из локального хванилища в удаленное. Естественно, проверяем, что каждая операция успешно завершена, и пишем все в логи.
Для отсылки сообщения администратору я использую XMPP сообщение, так как в организации поднят Jabber-сервер, и я больше люблю получить быстрое сообщение о сбое, чем лезть в почту, вбивая пароли, тыкая на ссылки, и ожидая пока браузер мне все отобразит. В любом случае никто не мешает вам использовать sendmail вместо sendxmpp.
Файл /usr/local/etc/XMPP_settings следующего содержания:

#логин_отправителя@домен;IP_jabber_сервера:порт_jabber_сервера пароль_отправителя login@domen;127.0.0.1:5222 password
//192.168.0.250/arhiv /mnt/archive cifs noauto,rw,iocharset=utf8,cp866,file_mod=0666,dir_mod=0777,noexec,_netdev,credentials=/root/.passwd_to_archive_directory 0 0

Теперь осталось только добавить задание в cron. Это можно сделать с помощью файла /etc/crontab, но я, в силу привычки к GUI, оставшейся в наследство от виндовс, пользую вэб-интерфейсы для таких случаев. Команда должна выполняться с правами рута, то бишь, к примеру, sudo bash backup_script. Добавляя команду в cron можно определить что она будет сразу выполняться от имени root`а

Читайте также:  Astra linux контроль печати

В ходе обсуждений затронули проблему разрастания логов. Пошел по простейшему (на мой взгляд) пути: будем хранить только последние N строк лога, например 300. В скрипт добавятся две строки, в которых мы сохраним последние 300 строк лога во временный файл, потом затрем им лог

tail -n 300 $LOGFILE >/tmp/unique_fantastic_filename.tmp mv -f /tmp/unique_fantastic_filename.tmp $LOGFILE
#!/bin/bash TN=docs-monthly #TN=docs-weekly #TN=docs-daily OF=$TN.tar.gz LOGFILE=/var/log/backup.log echo >>$LOGFILE echo "==================================================== $(date +'%d-%b-%Y %R')" >>$LOGFILE echo "Задание \"$TN\" запущено. " >>$LOGFILE OLD_IFS=$IFS IFS=$'\n' SRCD="/mnt/source/folder_1 /mnt/source/folder_2 /mnt/source/folder_N" TGTD="/var/backups/" TGTD2="/mnt/archive/" tar -czf $TGTD$OF $SRCD &>>$LOGFILE #tar -u -f $TGTD$OF $SRCD &>>$LOGFILE STATUS=$? IFS=$OLD_IFS if [[ $STATUS != 0 ]]; then rm $TGTD$OF &>>$LOGFILE echo "###########################################" >>$LOGFILE echo "### Произошла ошибка! Бэкап не удался. ###" >>$LOGFILE echo "###########################################" >>$LOGFILE echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не создан" | sendxmpp -t -f /usr/local/etc/XMPP_settings логин_получателя@домен &>>$LOGFILE else echo "Файл бэкапа сохранен как \"$TGTD$OF\"" >>$LOGFILE echo "Бэкап успешно завершен в $(date +'%R %d-%b-%Y')!" >>$LOGFILE echo "Монтирование файловой системы для резервного архива $TGTD_archive" >>$LOGFILE mount $TGTD2 &>>$LOGFILE if [[ $? != 0 ]]; then echo "#############################################################" >>$LOGFILE echo "### Произошла ошибка при монтировании резервного ресурса ###" >>$LOGFILE echo "#############################################################" >>$LOGFILE echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не скопирован на резервный ресурс" | sendxmpp -t -f /usr/local/etc/XMPP_settings логин_получателя@домен &>>$LOGFILE exit fi echo "Начато копирование файла на резервный ресурс" >>$LOGFILE cp -f $TGTD$OF $TGTD_archive$OF &>>$LOGFILE if [[ $? != 0 ]]; then echo "#############################################################" >>$LOGFILE echo "### Произошла ошибка при копировании на резервный ресурс ###" >>$LOGFILE echo "#############################################################" >>$LOGFILE echo "$(date +'%d-%b-%Y %R%nФайл') бекапа $OF не скопирован на резервный ресурс" | sendxmpp -t -f /usr/local/etc/XMPP_settings логин_получателя@домен &>>$LOGFILE else echo "Копирование файла успешно завершено в $(date +'%R %d-%b-%Y')!" >>$LOGFILE echo "Файл скопирован как \"$TGTD_archive$OF\"" >>$LOGFILE fi echo "Размонтирование файловой системы для резервного архива $TGTD_archive" >>$LOGFILE umount $TGTD2 &>>$LOGFILE echo "Все операции завершены успешно!" >>$LOGFILE fi tail -n 300 $LOGFILE >/tmp/unique_fantastic_filename.tmp mv -f /tmp/unique_fantastic_filename.tmp $LOGFILE exit

Источник

Оцените статью
Adblock
detector