Backup script for 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 mint планировщик задач

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

Теперь добавим условие — если процесс упаковки в архив 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`а

Читайте также:  Linux find файлы больше

В ходе обсуждений затронули проблему разрастания логов. Пошел по простейшему (на мой взгляд) пути: будем хранить только последние 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

Источник

Элементарный Bash скрипт для резервного копирования данных

Привет хабралюди, сейчас я расскажу как можно немного автоматизировать рутиную работу по подготовке бэкапов.

Читайте также:  Линукс процессы через терминал

В данном случае, мы не будем использовать мощные программы, или даже целые системы для резервного копирования данных, ограничимся самым доступным что у нас есть. А именно — Bash скриптом.

Что должен выполнять наш скрипт?

Бэкапить веб проект, а именно:
— Делать резервную копию базы MySQL.
— Делать резервную копию файлов.
— Структурировать это.

#!/bin/bash
PROJNAME= #Имя проекта
CHARSET= #Кодировка базы данных (utf8)
DBNAME= #Имя базы данных для резервного копирования
DBFILENAME= #Имя дампа базы данных
ARFILENAME= #Имя архива с файлами
HOST= #Хост MySQL
USER= #Имя пользователя базы данных
PASSWD= #Пароль от базы данных
DATADIR= #Путь к каталогу где будут храниться резервные копии
SRCFILES= #Путь к каталогу файлов для архивирования
PREFIX=`date +%F` #Префикс по дате для структурирования резервных копий

#start backup
echo «[———————————[`date +%F—%H-%M`]———————————]»
echo «[———-][`date +%F—%H-%M`] Run the backup script. »
mkdir $DATADIR/$PREFIX 2> /dev/null
echo «[++———][`date +%F—%H-%M`] Generate a database backup. »
#MySQL dump
mysqldump —user=$USER —host=$HOST —password=$PASSWD —default-character-set=$CHARSET $DBNAME > $DATADIR/$PREFIX/$DBFILENAME-`date +%F—%H-%M`.sql
if [[ $? -gt 0 ]];then
echo «[++———][`date +%F—%H-%M`] Aborted. Generate database backup failed.»
exit 1
fi
echo «[++++——][`date +%F—%H-%M`] Backup database [$DBNAME] — successfull.»
echo «[++++++—-][`date +%F—%H-%M`] Copy the source code project [$PROJNAME]. »
#Src dump
tar -czpf $DATADIR/$PREFIX/$ARFILENAME-`date +%F—%H-%M`.tar.gz $SRCFILES 2> /dev/null
if [[ $? -gt 0 ]];then
echo «[++++++—-][`date +%F—%H-%M`] Aborted. Copying the source code failed.»
exit 1
fi
echo «[++++++++—][`date +%F—%H-%M`] Copy the source code project [$PROJNAME] successfull.»
echo «[+++++++++-][`date +%F—%H-%M`] Stat datadir space (USED): `du -h $DATADIR | tail -n1`»
echo «[+++++++++-][`date +%F—%H-%M`] Free HDD space: `df -h /home|tail -n1|awk »`»
echo «[++++++++++][`date +%F—%H-%M`] All operations completed successfully!»
exit 0

Запускать можно парой способов:

— Простой запуск: ./backup.sh
— Запуск + запись в лог: ./backup.sh | tee backup.log
— а еще его можно в cron запихать: 00 20 * * 7 root sh /home/bond/backup.sh | tee /home/bond/backup/backup.log
После успешного завершения скрипта, мы увидим следующее:

bond@serv:~$ sudo sh backup.sh
[———————————[2009-02-14—12-28]———————————]
[———-][2009-02-14—12-28] Run the backup script.
[++———][2009-02-14—12-28] Generate a database backup.
[++++——][2009-02-14—12-29] Backup database [images] — successfull.
[++++++—-][2009-02-14—12-29] Copy the source code project [itmages].
[++++++++—][2009-02-14—12-29] Copy the source code project [itmages] — successfull.
[+++++++++-][2009-02-14—12-29] Stat datadir space (USED): 1,3G /home/bond/backup
[+++++++++-][2009-02-14—12-29] Free HDD space: 49G
[++++++++++][2009-02-14—12-29] All operations completed successfully!
bond@serv:~$

В итоге наши бэкапы складываются в каталог который вы указали, + резервные копии лежат в каталогах именованых по дате.

п.с. спасибо opkdx за хинт при написании.

Источник

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