
Ссылка на статью в формате MarkDown для Curl, кодировка RU.UTF-8
Синхронизация папок с помощью bash и rsync
Адрес статьи: nixscript.ru/sync-gechandesu
Я написал bash скрипт, позволяющий делать простую одностороннюю синхронизацию папок. Можно использовать для бэкапа файлов на съёмный носитель и вообще для синхронизации любых папок на компьютере.
Производить синхронизацию будем с помощью rsync.
Собственно, вот весь скрипт:
#!/bin/bash
syncfrom=$1
syncto=$2
if ! [ -d "$syncfrom" ]; then
echo 'Source directory does not exist!'
elif [ "$(ls "$syncfrom" | wc -l)" -eq 0 ]; then
echo "Source directory is empty!"
else
while true
do
rsync -aP --delete "$syncfrom" "$syncto"
sleep 2
done
fi
Что оно делает
Скрипт в бесконечном цикле выполняет синхронизацию двух папок и имеет следующий синтаксис:
sync.sh /source/dir/ /destination/dir/
Изменения папки /source/dir/ применяются к папке /destination/dir/dir - переименование файлов, удаление, перемещение и т.п.
Как это работает
Разберём весь скрипт по порядку.
Прежде всего нас интересуют вот эти строчки:
#!/bin/bash
syncfrom="$1"
syncto="$2"
В первой строке мы указываем путь к интерпретатору. Это стандартное начало для bash скриптов.
В следующих двух строчках вводим переменные syncfrom и syncto. Это будут наши параметры, которые мы будем указывать уже при запуске скрипта.
syncfrom будет содержать путь к исходной папке, а syncto путь к папке, в которую будет производиться копирование.
Присваиваем им соотвестственно $1 и $2, что означает, что следующая команда запишет путь /source/dir/ в значение переменной syncfrom и путь /destination/dir/ в значение syncto:
sync.sh /source/dir/ /destination/dir/
Цифры 1 и 2 означают порядковый номер параметра. Если бы я указал 0, то это было бы название скрипта.
Самое интересное в скрипте это строка с вызовом rsync. Она заключена в бесконечный цикл, чтобы постоянно мониторить нашу исходную папку и при необходимости производить синхронизацию.
while true
do
rsync -aP --delete "$syncfrom" "$syncto"
sleep 2
done
Рассмотрим ближе строку
rsync -aP --delete "$syncfrom" "$syncto"
Здесь параметр -aP означает, что rsync будет действовать рекурсивно и выводить лог синхронизации в терминал.
--delete разрешает удаление, если файлы/папки были удалены из исходной папки. Если вам это не нужно, просто не указывайте этот параметр.
$syncfrom и $syncto это, как уже выше было сказано, пути к папкам.
Если вам надо, чтобы какие-то файлы не попадали в синхронизацию, можно настроить исключения. Делается это следующим образом -- нужно указать параметры --exclude:
rsync -aP --delete --exclude=desktop.ini --exclude=*.tmp "$syncfrom" "$syncto"
В этом примере исключаются файлы desktop.ini и все файлы с расширением .tmp.
В том же цикле, что и rsync вызывается команда sleep со значением 2. Это пауза в две секунды. Она тут ради экономии ресурсов компьютера, чтобы не проводить синхронизацию много тысяч раз в секунду. Раз в две секунды для наших целей вполне достаточно.
Если файл не успеет скопироваться за две секунды, то его копирование будет продолжено на следующей итерации и в итоге он будет записан целиком.
Так как в параметрах к rsync есть параметр --delete у нас появляется потенциальная угроза потерять данные в случае банальной опечатки или указания пустой директории как исходной.
Для того, чтобы синхронизация не началась с пустой или несуществующей папкой нужно написать обработчики. За это отвечают строки:
if ! [ -d "$syncfrom" ]; then
echo 'Source directory does not exist!'
elif [ $(ls "$syncfrom" | wc -l) -eq 0 ]; then
echo "Source directory is empty!"
else
...
Строка c if проверяет существует ли указанная исходная папка и возвращает сообщение об ошибке, если результат ложь.
elif проверяет не пустая ли папка и сообщает, если это так.
Если оба условия выполнились, то синхронизация начинается.
! Важно. Так как проверка условий происходит до запуска цикла, то синхронизация продолжится если файлы будут удалены после запуска скрипта. Т.е. в сценарии, когда папка оказалась пустой, с уже выполняющейся синхронизацией, это приведёт к удалению файлов в папке назначения.
Как использовать
Скачать скрипт: https://github.com/gechandesu/sync
Положите файл sync.sh в любое удобное место и дайте ему права на выполнение:
chmod +х sync.sh
Далее выполните скрипт с указанием параметров:
sync.sh /source/dir/ /destination/dir/
где /source/dir/ это путь к исходной папке, а /destination/dir/ путь к папке назначения.
Если вам нужно, можете прикрутить эту команду в автозагрузку системы, чтобы постоянно бэкапить свои файлы :)
Автор: gechandesu 10.05.2019
Статья написана в формате MarkDown и сконвертирована в HTML с помощью скрипта Parsedown.