понедельник, 14 сентября 2020 г.

Запуск процесса синхронизации при изменении содержания источника данных (автоматизация)


Идея автоматизации выполнения данной задачи родилась из периодической "забывчивости" осуществления резервирования данных на регулярной основе. Полагаю, что у каждого имеются файлы, которые было бы обидно потерять в случае какого-либо сбоя на файловой системе или отказа физического носителя.
 
Реализация рассматривается на примере создания резервной копии личной библиотеки книг fb2. В качестве источника рассматривается несколько папок, каждая из которых имеет своё назначение, например "прочитанные", "планируется прочитать", "только получено", "решение ещё не принято" и т.д. и т.п.

Решение создавалось для решения прикладной задачи личных нужд и не претендует на материал для обучения или описание единственно правильного написания сценария sh.

Необходимость запуска синхронизации определяется путём вычисления разницы между предыдущим содержанием папок и содержанием этих папок на момент запуска синхронизации. В моём случае такой запуск осуществляется по расписанию (см. пользовательское задание cron).

Мной были созданы 2 файла сценариев sh и 2 папки.


Папка Lists содержит файлы, на основании которых определяется необходимость запуска синхронизации. Файлы сценариев account.sh и do.sh представляют из себя набор команд, осуществляющих выполнение всех действий. Папка MEGAsync содержит данные, необходимые для работы конкретной учётной записи MEGA. Поскольку у меня имеется не один аккаунт, то существование данной папки определяется алгоритмом запуска клиента MEGA под разными учётными записями (подробности).

В папке Lists содержатся файлы list.txt , s.txt , value.txt  Их назначение поясняется в комментариях к листингу сценария do.sh


В приводимых листингах сценариев указываются пути для моего случая. Если возникнет желание применить их в своей системе, то укажите свои пути. Например, это касается значений log= , conf= , /home/minter/... 

Пояснения в сценариях читать после символа #.

Выполнение задачи осуществляется путём запуска файла do.sh

#!/bin/sh
#  Указывается файл протокола работы в конкретный день месяца.
day=`date '+%d'` 
log=/home/minter/Reports/mega/$day.data2.txt
#  Если файл log не существует, то он создаётся
if [ -f $log ]; then
  :
else
  > $log
  echo "  " >> $log
fi
# В conf указываются пути всех дополнительных файлов
conf=/home/minter/configs/mega/internet
# Файлы list.txt содержат список хранящихся в них объектов
# Аналогичные данные содержатся и в файлах s.txt
# Файлы s.txt содержат данные состояния до анализа необходимости синхронизации,
# то есть состояния после последней синхронизации.
# Файлы list.txt содержат сведения о содержании папок на момент принятия решения
# о необходимости осуществления синхронизации.
list1=$conf/Lists/list1.txt
list2=$conf/Lists/list2.txt
list3=$conf/Lists/list3.txt
list4=$conf/Lists/list4.txt
list5=$conf/Lists/list5.txt
list6=$conf/Lists/list6.txt
s1=$conf/Lists/s1.txt
s2=$conf/Lists/s2.txt
s3=$conf/Lists/s3.txt
s4=$conf/Lists/s4.txt
s5=$conf/Lists/s5.txt
s6=$conf/Lists/s6.txt
# Значения stor являются указания путей к папкам с синхронизируемым данным.
# Эти значения используются в командах создания списков содержания этих папок.
stor1=/home/minter/Books
stor2=/home/minter/FBbooks
stor3=/home/minter/Downloads/palemoon
stor4=/home/minter/Downloads/waterfox
stor5=/home/minter/Downloads/yandex
stor6=/home/minter/Downloads/opera
# Создаются списки содержания папок, подлежащих синхронизации с облаком.
# В комплекте поставки Linux Mint "из коробки" программа tree отсутствует.
# Её необходимо установить дополнительно:  sudo apt install -y tree
tree --noreport $stor1 > $list1
tree --noreport $stor2 > $list2
tree --noreport $stor3 > $list3
tree --noreport $stor4 > $list4
tree --noreport $stor5 > $list5
tree --noreport $stor6 > $list6
# Вычисляются величины, на основании которых сценарий будет принимать
# решение о необходимости осуществления запуск клиента MEGA.
# Сравнивается содержание файлов list.txt и s.txt
# Если файлы равны, то величине присваивается значение 0.
# Если файлы не равны, то величине присваивается значение 1.
# Действие производится для каждой из синхронизируемых папок.
# write value for stor1
if cmp -s $list1 $s1
  then
     v1=0
     echo $v1 > $conf/Lists/value1.txt
  else
     v1=1
     echo $v1 > $conf/Lists/value1.txt
fi
# write value for stor2
if cmp -s $list2 $s2
  then
     v2=0
     echo $v2 > $conf/Lists/value2.txt
  else
     v2=1
     echo $v2 > $conf/Lists/value2.txt
fi
# write value for stor3
if cmp -s $list3 $s3
  then
     v3=0
     echo $v3 > $conf/Lists/value3.txt
  else
     v3=1
     echo $v3 > $conf/Lists/value3.txt
fi
# write value for stor4
if cmp -s $list4 $s4
  then
     v4=0
     echo $v4 > $conf/Lists/value4.txt
  else
     v4=1
     echo $v4 > $conf/Lists/value4.txt
fi
# write value for stor5
if cmp -s $list5 $s5
  then
     v5=0
     echo $v5 > $conf/Lists/value5.txt
  else
     v5=1
     echo $v5 > $conf/Lists/value5.txt
fi
# write value for stor6
if cmp -s $list6 $s6
  then
     v6=0
     echo $v6 > $conf/Lists/value6.txt
  else
     v6=1
     echo $v6 > $conf/Lists/value6.txt
fi
# Считываются полученные значения value.txt
# Каждое из значений записывается в переменную h
h1=`cat $conf/Lists/value1.txt`
h2=`cat $conf/Lists/value2.txt`
h3=`cat $conf/Lists/value3.txt`
h4=`cat $conf/Lists/value4.txt`
h5=`cat $conf/Lists/value5.txt`
h6=`cat $conf/Lists/value6.txt`
# Вычисляется сумма переменных h
# Полученная сумма сравнивается со значением 0.
# Если результат сравнения "не равно 0", то это означает, что содержание
# хоть одной из синхронизируемых папок было изменено, поэтому
# необходимо запустить синхронизацию.
# Если результат сравнения "равно 0", то это означает, что с момента предыдущей
# синхронизации содержание папок не изменилось и необходимость в
# осуществлении их синхронизации с облаком отсутствует. 
res1=$(( $h1 + $h2 + $h3 + $h4 + $h5 + $h6 ))
res0=0
if [ $res1 -eq $res0 ]; 
  then
     # в файл протокола вносится запись, что необходимости что-то делать не имеется.
     time=`date '+%H.%M.%S'`
     echo "$time nothing to do" >> $log
     echo "  " >> $log
  else
     # при необходимости синхронизации запускается клиент MEGA
     # запуск клиента MEGA осуществляется с параметром 
     # export DISPLAY=:0, так как клиент является графическим приложением
     export DISPLAY=:0 && $conf/account.sh
fi
# Содержание файлов s.txt перезаписывается содержанием файлов list.txt
cp $list1 $s1
cp $list2 $s2
cp $list3 $s3
cp $list4 $s4
cp $list5 $s5
cp $list6 $s6
time=`date '+%H.%M.%S'`
echo "$time lists replaced" >> $log
echo "  " >> $log
exit

Листинг сценария account.sh

#!/bin/sh
# Указывается расположение данных учётной записи MEGA
conf=/home/minter/configs/mega/data2
# Указывается расположение файла протокола задания
day=`date '+%d'`
log=/home/minter/Reports/mega/$day.data2.txt
# Так как в моём случае аккаунтов MEGA несколько, то 
# данные для предыдущие данные клиента MEGA удаляются
# и записываются данные нужной учётной записи MEGA.
rm -R "/home/minter/.local/share/data/Mega Limited/MEGAsync"
cp -R $conf/MEGAsync "/home/minter/.local/share/data/Mega Limited/MEGAsync" 
time=`date '+%H.%M.%S'`
echo "$time account data copied" >> $log
fi
sleep 5
# Запуск клиента MEGA. Запуск сопровождается отображением
# уведомления в верхней части экрана.
# В некоторых ubuntu-подобных дистрибутивах компонент notify-send
# может отсутствовать и его необходимо установить. 
# sudo apt install -y libnotify-bin
# Дополнительный материал по оформлению всплывающих сообщений.
notify-send --icon=/home/minter/.local/share/icons/gnome/48x48/emblems/emblem-sync-megasync.png "MEGA starting"
time=`date '+%H.%M.%S'`
echo "$time mega started" >> $log
# Значок & после команды запуска клиента указывает на
# переход к следующей команде. Если он будет отсутствовать,
# то следующая команда не будет выполнена до тех пор, пока
# будет активна команда megasync.
megasync &
# sleep 600 означает "спать 10 минут". Планируется, что 10 минут
# достаточно для выполнения синхронизации. 
sleep 600
# Команда завершения работы клиента MEGA без участия пользователя.
client="$(pidof megasync)"
kill -15 ${client}
time=`date '+%H.%M.%S'`
echo "$time mega stoped" >> $log
sleep 5
# После завершения работы клиента данные, относящиеся к процессу
# синхронизации с облаком MEGA записываются в папку с настройками
# учётной записи. Предыдущие данные удаляются, а данные
# выполненного сеанса синхронизации записываются на их место.
rm -R $conf/MEGAsync
cp -R "/home/minter/.local/share/data/Mega Limited/MEGAsync" $conf/MEGAsync
notify-send --icon=/home/minter/.local/share/icons/gnome/48x48/emblems/emblem-sync-megasync-blue.png "MEGA backuped"
time=`date '+%H.%M.%S'`
echo "$time account data copied to backup" >> $log
exit

Если имеется только 1 учётная запись MEGA, то содержание файла account.sh можно упростить до следующего:

#!/bin/sh
day=`date '+%d'`
log=/home/minter/Reports/mega/$day.data2.txt
notify-send --icon=/home/minter/.local/share/icons/gnome/48x48/emblems/emblem-sync-megasync.png "MEGA starting"
time=`date '+%H.%M.%S'`
echo "$time mega started" >> $log
megasync &
sleep 600
client="$(pidof megasync)"
kill -15 ${client}
time=`date '+%H.%M.%S'`
echo "$time mega stoped" >> $log
exit

Необходимость в наличии папки MEGAsync (см. в начале публикации) будет отсутствовать, так как не имеется необходимости в перезаписи содержания папки 
~/.local/share/data/Mega Limited/MEGAsync

Комментариев нет:

Отправить комментарий