Привет, Хабр! В арсенале системного администратора и разработчика есть множество инструментов для переноса данных. Мы копируем файлы десятки раз в день: cp для локальных копий, scp для удалённых серверов. Но что если задача сложнее? Нужно не просто скопировать, а синхронизировать два дерева файлов, дёргая по сети лишь изменившиеся данные? Или поддерживать в актуальном состоянии зеркало веб‑контента?

Идея написать эту статью (а впоследствии и целую серию) родилась из многократного наблюдения одной и той же истории: многие знакомые годами используют rsyncпроцентов на 10, даже не зная о возможностях, которые «прячутся» за его синтаксисом. А те, кто пытается погрузиться глубже, часто сталкиваются с отсутствием более‑менее полных руководств с примерами.

О чём эта статья?

  • Фундамент: как правильно путями в rsync и почему слеш в конце решает всё.

  • Три основных режима работы: локально, с сервером и между серверами.

  • Разбор «волшебного» флага -a: что скрывается под капотом.

  • Главные опции: как сделать вывод подробным, а работу — безопасной.

  • Синхронизация поверх SSH: работа с нестандартными портами.

  • Самые опасные «грабли» и как их избежать.

Это первая статья из цикла. В ней я сознательно не касаюсь таких продвинутых тем, как построение систем бэкапов с инкрементальными копиями с помощью --link-dest или сложных фильтров для исключения файлов. Оставлю это для следующих частей, чтобы не перегружать материал.

Глава 1: фундамент. Синтаксис и первые шаги

1.1. Основной синтаксис: откуда, куда и основа слешей

Всё многообразие возможностей rsync упаковано в простую и элегантную структуру:

rsync [ОПЦИИ] ИСТОЧНИК НАЗНАЧЕНИЕ

Разберём каждый компонент, дабы сформировать полную картину происходящего.

ИСТОЧНИК и НАЗНАЧЕНИЕ: три лика путей

rsync универсален: он работает как с локальными, так и с удалёнными путями. Формат путей определяет характер всей операции.

  • Локальный путь: обычный путь к файлу или директории на текущей машине:

    • /home/user/docs/

    • ./local_dir_example/

  • Удалённый источник (PULL): забрать файлы с удалённого сервера:

    • Формат: пользователь@сервер:путь

    • Пример: user@backup-server:/var/backups/

  • Удалённое назначение (PUSH): отправка файлов на удалённый сервер:

    • Формат: пользователь@сервер:путь

    • Пример: user@web-server:/var/html

Важно: для работы с удалённым серверами должен быть настроен доступ по SSH (лучше по ключам), так как rsyncбудет постоянно запрашивать пароль.

Слэш на конце пути (/src vs /src/)

Поведение rsync кардинально меняется в зависимости от того, поставили мы слеш в конце пути к исходной директории или нет. Это фундаментальное поведение, и его нужно запомнить раз и навсегда.

Ключевое правило: слеш в конце пути к источнику означает "копировать СОДЕРЖИМОЕ этой директории". Отсутствие слеша означает "копировать САМУ директорию и её содержимое".

Сценарий 1: rsync -a /src/ /dest/

  • Что происходит: rsync берет все файлы и папки, которые находятся внутри директории /src/, и копирует их непосредственно в /dest/.

  • Результат в /dest/:

/dest/file1.txt
/dest/subdir/
/dest/subdir/file2.txt
  • Сама папка src/ внутри /dest/ не создаётся.

  • Аналогия: «вывали содержимое коробки src в коробку dest».

Сценарий 2: rsync -a /src /dest/

  • Что происходит: rsync берет саму директорию src вместе со всем её содержимым и копирует её внутрь директории /dest/.

  • Результат в /dest/:

/dest/src/       #  <-- Сама папка создаётся
/dest/src/file1.txt
/dest/src/subdir/
/dest/src/subdir/file2.txt
  • Аналогия: «поставь коробку src целиком внутрь коробки dest».

Последствия

Представьте, что мы хотим синхронизировать содержимое веб-сайта в папку /var/www/html/ на сервере.

  • Цель: чтобы в /var/www/html/ лежали файлы index.html, style.css и т.д.

Ошибка (без слеша):

rsync -a ./build user@server:/var/www/html/

Результат: на сервере появится структура /var/www/html/build/index.html, и сайт перестанет работать, потому что веб-сервер ищет файлы прямо в /var/www/html/.

Верно (со слешом):

rsync -a ./build/ user@server:/var/www/html/

Результат: файлы из build/ попадут прямо в /var/www/html/, и сайт будет работать корректно.

Обратная ситуация, когда мы хотим сохранить структуру папок. Допустим, мы делаете бэкап домашней директории.

Ошибка (со слешом):

rsync -a /home/user/ /backups/

Результат: все файлы и папки из /home/user/ будут свалены в кучу внутри /backups/. Мы не сможем понять, что из этого было в Documents, а что в Pictures.

Верно (без слеша):

rsync -a /home/user /backups/

Результат: в /backups/ создастся папка user/, внутри которой будет точное зеркало вашей домашней директории с сохранением всей структуры.

Простое правило для запоминания: всегда думать о том, что должно оказаться внутри целевой папки (приёмника). Хотите, чтобы там были файлы и папки из источника? Ставим слеш в конце источника. Хотите, чтобы там появилась сама папка-источник? Не ставьте слеш.

Это первое, что нужно проверять, если после запуска rsync файлы оказались не там, где Вы ожидали. Всегда используйте --dry-run (-n) для проверки перед выполнением опасных команд.

1.2. Три сценария использования: локальный, Push/Pull и удалённый мост

Одна из наиболее сильных сторон rsync - его способность работать в различных сетевых конфигурациях. Ваша машина может быть: источником данных, приёмником данных, "посредником" между серверами.

Локальное копирование (Local-to-Local)

Самый простой режим, альтернатива команде cp -r, но с умным rsync.

Основная суть: и источник, и приёмник находятся на одной и той же машине. Используется для точного зеркалирования структуры каталогов с сохранением прав, владельцев, временных меток (-a). Отлично подходит для создания быстрых локальных бэкапов или синхронизации папок.

  • Синтаксис:

rsync [ОПЦИИ] /пусть/к/источнику /путь/к/приёмнику
  • Для примера: синхронизируем папку projects в бэкап-директорию, сохраняя все атрибуты файлов.

rsync -av --delete ~/projects/ /mnt/backup_disk/projects_backup/

Копирование с удалённым сервером (Push и Pull)

Данный сценарий использования является наиболее распространённым. Машина обменивается данными с удалённой машиной.

Основная суть: один из путей (источник/приёмник) указан с префиксом user@host:.

  • Режим PUSH (отправить на удалённый сервер): отправка данных с локальной машины на удалённый сервер. Посмотрим, как это выглядит:

rsync [ОПЦИИ] /локальный/источник user@remote-server:/удалённый/приёмник

Посмотрим на примере: необходимо развернуть код веб-сайта на продакшен-сервер:

rsync -avz --delete ./build/ user@web-server:/var/www/mysite/
  • Режим PULL (забрать с удалённого сервера): на локальной машине забрать данные с удалённого сервера. Выглядит следующим образом:

rsync [ОПЦИИ] user@remote-server:/удалённый/источник /локальный/приёмник

Снова на примере: скачать логи с сервера для, например, анализа:

rsync -avz user@app-server:/var/log/myapp/ ./server_logs/

Важно: в перечисленных сценариях SSH-соединение устанавливается между локальной машиной и удалённым сервером. Весь трафик идёт через локальную машину.

Удалённый мост (Remote-to-Remote)

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

Принцип: оба пути - и источник, и приёмник - являются удалёнными. Используется для:

  1. Экономии трафика и времени: данные текут напрямую между server_1 и server_2, минуя локальную машину. Это критически важно при передаче больших объёмов данных, если у Вас медленный канал.

  2. Автоматизация: можно с одной машины управлять процессами синхронизации в инфраструктуре.

Теперь посмотрим синтаксис:

rsync [ОПЦИИ] user@source-server:/путь/ user@dest-server:/путь/

Вновь, рассмотрим пример: перенести бэкапы с одного сервера на другой.

rsync -avz --delete user@storage-old:/backups/ user@storage-new:/backups/

Примечание: для работы данного режима, локальная машина должна иметь SSH-доступ по ключам к обоим удалённым серверам. rsync установит 2 SSH-соединения: одно для чтения с источника, другое - для записи на приёмник, и будет перенаправлять данные между ними.

Подведу итоги: безусловно, выбор режима зависит от задачи. Нужно быстро скопировать локальные данные - используется первый "режим". Нужно обменяться со своим сервером - второй. Перегнать террабайты данных между серверами - смело используется третий режим, дабы не нагружать свой канал.

1.3. Флаг -a: архивный режим и что скрывается под капотом

Флаг -a (или --archive) - без преувеличения, самый главный и часто используемый ключ в rsync. Часто называют "режимом архивирования", он является неким "золотым стандартом", эталоном для большинства задач копирования. Почему? Всё просто, он предписывает rsync сохранять практически всё, что делает файл - файлом: метаданные и структуру.

В каком-то смысле, -a - не просто один флаг, а некий "макрос", который раскрывается в группу опций. Глянем на состав: -a = -rlptgoD

Разберем буквы этого "заклинания":

  • -r (--recursive): копировать рекурсивно. Без этой опции rsync скопирует только файлы в указанной директории, проигнорировав все вложенные папки. Это "основа основ" для работы с директориями.

  • -l (--links): сохранять симлинки как симлинки. Если в источнике есть символическая ссылка, rsync воссоздаст её в пункте назначения как ссылку, а не скопирует содержимое файла, на который она указывает. Это критически важно для сохранения целостности структуры многих приложений.

  • -p (--perms): сохранять права доступа. Файлы и папки на приёмнике будут иметь те же права (chmod), что и на источнике (к примеру, 755, 644).

  • -t (--times): сохранять временные метки. rsync сохраняет время последнего изменения файла (mtime). Не только для красоты - эта опция помогает rsync на последующих запусках определять, какие файлы изменились и нуждаются в обновлении.

  • -g (--group): сохранять группу. Файлы будут принадлежать той же группе, что и на источнике.

  • -o (--owner): сохранять владельца. rsync попытается сохранить владельца файла (UID). Важное исключение: для работы этой опции при копировании на удалённый сервер вам обычно потребуются права root на приёмнике.

  • -D: сохранять device files (специальные файлы устройств). Это эквивалентно одновременному использованию --devices --specials. Нужно для копирования таких сущностей, как /dev/ (например, для создания точных копий системных разделов), но на практике крайне редко встречаю в повседневных задачах копирования.

Почему почти всегда стоит использовать -a?

Флаг -a - это "выражение намерения". Вы говорите утилите что-то вроде: "Я хочу не просто перенести биты данных, а хочу создать точную копию структуры и свойств исходных файлов".

Приведу пример двух сценариев с -a и без него:

Сценарий без -a:
Копируется, например, веб-сайт командой rsync -r. Файлы скопируются, но:

  • Скрипты могут потерять права на исполнение (chmod +x)

  • Папки могут потерять права на запись

  • Символические ссылки превратятся в копии файлов, что может сломать логику сайта и удвоить занимаемое место

  • rsync не сможет эффективно определять изменённые файлы по временным меткам на последующих запусках

Фактически, получается некая "куча" данных, которые могут не "завестись".

Сценарий с -a:
Копируется веб-сайт командой rsync -a. Мы получаем:

  • Точную зеркальную копию, готоую к работе

  • Корректные права доступа

  • Правильные симлинки

  • Основу для быстрой инкрементальной синхронизации в будущем

Как итог: почти всегда стоит начинать с флага -a. Это базовая опция для 90% задач. Безусловно, если речь не идёт о каком-то специфическом поведении (к примеру, игнорировать симлинки), стоит отключить конкретную опцию из состава -a или отказаться в пользу ручного подбора флагов под Ваши нужды.

Глава 2: ликбез по ключевым опциям

2.1. Вижу всё: подробный вывод и самая важная опция -n

Работать с подобным инструментом "вслепую" - верный путь к катастрофе, верно? rsync предоставляет 2 ключевые опции, которые позволяют увидеть план действий перед реальным выполнением.

-v (--verbose): режим подробного вывода

По умолчанию rsync работает "молча". Если всё прошло успешно, можно не увидеть никакого вывода, из-за чего порой возникают вопросы: "А что оно вообще сделало?".

Флаг -v включает подробный вывод, показывая, какие файлы и директории передаются. Можно добавлять несколько v для увеличения уровня детализации (к примеру, -vv или -vvv), что часто бывает полезно для отладки сложных проблем. Рассмотрим на примере:

rsync -av ~/documents/ /backup/

Выведет список всех скопированных файлов и директорий, а в конце - сводку с количеством переданных данных и общим размером.

Зачем в целом данный флаг использовать?

  • Для визуального подтверждения, что процесс запустился и передаются нужные файлы

  • Для ведения лога операций копирования

  • Для диагностики (в сочетании с -n, о нём ниже)

-n (--dry-run): без преувеличений, самая важная опция в арсенале

Это главный инструмент безопасности. Всегда стоит использовать эту опцию перед выполнением любой новой, сложной или потенциально небезопасной команды rsync (особенно с --delete!).

Флаг -n заставляет rsync не выполнять никаких реальных изменений на стороне приёмника. Он лишь имитирует работу и демонстрирует в выводе (обычно с -n), что бы он сделал, если бы команда выполнялась без него.

Почему это критически (!) важно?

  • Предотвращает ошибки: позволяет увидеть последствия опасных флагов (таких, как --delete) до того, как они "наделают делов" (необратимо удалят файлы).

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

  • Оценивает объём работ: демонстрирует, сколько файлов будет передано/удалено, что помогает оценить время и трафик.

Рассмотрим на примере сценария:

Итак, я хочу синхронизировать папку с удалённым сервером и удалить на сервере всё лишнее, но команда меня напрягает (выглядит опасно):

rsync -av --delete ~/projects/ user@server:/backups/projects/

Как лучше действовать? Проверка (Dry Run). Сначала запустим симуляцию:

rsync -avn --delete ~/projects/ user@server:/backups/projects/

Внимательно изучаю вывод. rsync покажет все файлы, которые будут отправлены и, что самое главное, все файлы на сервере, помеченные к удалению.

Далее, могу выполнять. Если в выводе симуляции нет ничего подозрительного и всё выглядит так, как было запланировано изначально - смело запускаю команду без флага -n:

# Мы убедились, в симуляции всё "ок", делаем по-настоящему
rsync -av --delete ~/projects/ user@server:/backups/projects/

Вывод: сочетание -avn (Archive, Verbose, Dry-Run) - обязательный ритуал перед любой ответственной (и не очень) операцией с rsync. Потратив N секунд на симуляцию - можно спастись от часов восстановления данных. Этот флаг - некий предохранитель файлов.

2.2. Скорость и контроль: сжатие, докачка и ограничение трафика

rsync не просто копирует данные, он делает это умно. Эти опции помогают оптимизировать процесс передачи, особенно по сети, и дают контроль над ним.

-z (--compress): сжатие "на лету"

Включает сжатие данных перед отправкой по сети. Файлы сжимаются "на лету" на стороне отправителя и распаковываются на стороне получателя. Фактически, прозрачный процесс, который не затрагивает файлы на диске - они остаются в исходном виде.

Важно понять, когда использовать/не использовать эту опцию?

Стоит использовать: при работе с медленным или лимитированным сетевым каналом. Это основная цель опции. Сжатие экономит трафик и зачастую ускоряет передачу текстовых файлов, логов, кода и т.д., так как время на сжатие/распаковку меньше, чем время на передачу лишних (не сжатых) данных.

Не стоит использовать:

  • При локальном копировании (/local/path - /other/local/path). Сжатие бессмысленно нагрузит процессор, так как данные идут не по сети.

  • При передаче уже сжатых файлов. Любые архивы (.zip, .tar.gz) практически не сжимаются повторно (разница будет крайне мала или будет отсутствовать вовсе). Это бесполезная трата ресурсов CPU на обеих сторонах без получения минмального "выигрыша" в трафике.

Итог: по умолчанию используйте -z для любых операций по сети, если не требуется копировать "тонну" уже сжатых бинарных данных.

--progress: визуализация процесса

Эта опция покажет прогресс для каждого передаваемого файла: его имя, процент выполнения, объём переданных данных и оставшееся время. Очень хорошо дополняет -v (--verbose или "режим подробного вывода").

Цель использования? При передаче какого-то количества больших файлов бывает важно видеть прогресс, а не просто слепо ожидать завершения. Флаг поможет "справиться" с тревогой. "А не зависло ли всё...?".

--partial и --partial-dir=DIR: умная докачка

Поведение rsync по умолчанию при прерывании передачи: он удаляет не до конца переданный файл на "приёмнике", чтобы в следующий раз начать его заново с нуля. Далеко не всегда это оптимально

--partial: "говорит" rsync не удалять частично переданные файлы. В следующий раз он попытается докачать их с того места, где закончил.

--partial-dir=DIR: более продвинутый и безопасный аналог. rsync будет сохранять частичные файлы не в целевую директорию, а в указанную временную (DIR). После успешной полной передачи файл перемещается на своё законное место. В чём преимущества:

  1. Безопасность: в папке не будет "битых" частичных файлов

  2. Скорость: rsync может корректно определить, что это тот же частичный файл и продолжить нужного места.

  3. Удобство: можно легко чистить старые частичные файлы из одной временной папки.

Пример:

rsync -av --progress --partial-dir=.partial-dir user@server:/big/file.iso ./

--bwlimit=RATE (Limit I/O bandwidth): ограничение скорости

Жёсткое ограничение скорости передачи данных. Значение указывается в килобайтах в секунду (KB/s).

Почему это важно?

  • Не нагружать канал на основном сервере. Постоянная синхронизация терабайтов данных спокойно съест всю пропускную способность сети, что приведёт к "лагающему" сайту, SSH-сессии и иных критичных сервисов.

  • Часто важным аспектом является "беспрерывность бизнес-процессов". Ограничением можно гарантировать, что операция бэкапа или синхронизации не помешает основному бизенс-процессу.

  • И, основная причина: бесконтрольная нагрузка на сеть - одна из причин возникновения "внезапных" проблем.

Пример: необходимо ограничить скорость передачи до 5 мегабит в секунду (около 5000 килобит / 8 = 652 KB/s)

rsync -av --bwlimit=625 user@server:/data/ ./backup/

Или до 1 МБ/с (1024 KB/s):

rsync -av --bwlimit=1024 user@server:/data/ ./backup/

Вывод: комбинация данных опций позволяет создавать эффективные и, что самое главное, предсказуемые и безопасные для прода процессы синхронизации. Не стоит забывать о --bwlimit, когда приходится работать с рабочими серверами.

2.3. Сила и опасность: что делать с существующими файлами

Эти опции определяют не только то, что добавится при синхронизации, но и то, что может быть удалено. Очень важно понять принцип их работы, так как неверное использование - короткий путь к катастрофе.

--delete: опасная мощь идеальной синхронизации

Эта опция заставляет rsync сделать целевую директорию - идеальной зеркальной копией исходной. Она удаляет на приёмнике все файлы и папки, которых в источнике нет.

Почему это главная опасность? Представим сценарий:

  1. Случайно указана пустая или неверная папка в качестве источника.

  2. Уверенно запускаем: rsync -av --delete /пустая/папка/ /важная/база/данных/

  3. rsync выполняет /важная/база/данных точным зеркалом пусто папки. То есть, удаляет всё содержимое... Восстановление данных после этой операции часто является невозможным.

Правила безопасного использования:

  • Всегда сначала -n (--dry-run). Перед любой командой с --delete всегда необходимо использование флага -n и внимательное изучение вывода. Стоит обратить внимание на строи с пометкой deleting - это те файлы, которые будут уничтожены.

# Первоочередно используем "симуляцию". Смотрим, что будет удалено
rsync -avn --delete ~/projects/ /backups/projects/
# Внимательно читаем вывод. Если всё устраивает, переходим далее

# Можем выполнять. Запускаем без фалга -n
rsync -av --delete ~/projects/ /backups/projects/
  • Тройная проверка путей. Необходимо убедиться, что пути источника и приёмника указаны абсолютно верно. Не забываем про слеши (/).

  • Возможно использование --delete-delay или --delete-during. Данные опции удаляют файлы во время передачи, а не в начале, что чуть более безопасно и зачастую эффективно.

--ignore-existing: игнорирование существующих файлов

rsync будет копировать только те файлы, которых ещё нет на приёмнике. Если файл с данным именем уже существует в цели, он будет проигнорирован, даже если содержимое или метаданные отличаются.

Когда стоит использовать?

  • Для первоначального заполнения бэкапа, когда присутствует уверенность, что файлы на приёмнике не менялись и их не нужно перезаписывать.

  • Если необходимо добавить новые файлы, но нельзя трогать старые (к примеру, актуализировать фотографии с телефона в архив, куда ранее уже выгружались копии).

--update / -u: обновление только более старых файлов

rsync будет копировать файл только в том случае, если файл в источнике новее (по дате изменения), чем файл на приёмнике. Если файл на приёмнике новее или такой же, он будет проигнорирован.

В чём отличие от --ignore-existing?

  • --ignore-existing смотрит только на факт существования файла.

  • --update / -u смотрит на временную метку и обновляет файлы, если они старее.

Когда стоит использовать?

  • Более "умная" и безопасная стратегия для регулярных бэкапов или синхронизации. Она защищает от случайной перезаписи более новой версии файла старой.

  • Очень подходит, когда изменения могли вноситься с обеих сторон и необходимо "пропихнуть" только наиболее свежие изменения с источника, не трогая при этом файлы, которые новее на приёмнике.

Сравнительная таблица для ясности:

Ваша цель

Опция

Поведение для файла, который есть и там, и там

Идеальное зеркало

--delete

Файл на приёмнике будет перезаписан файлом из источника. Если файла в источнике нет - он будет удалён с приёмника.

Только добавить новое

--ignore-existing

Существующие файлы на приёмнике игнорируются полностью, даже если они старее.

Обновить, если старее

--update / -u

Файл на приёмнике будет перезаписан только если файл в источнике новее.

Вывод: --delete - "обоюдоострое" оружие. Это основа для создания чистых бэкапов, но требующая максимальной концентрации. --update - более осторожный и часто более подходящий выбор для повседневных задач. Основной посыл - --delete всегда сначала с -n!

Глава 3: rsync поверх SSH - безопасная синхронизация

3.1. SSH как транспорт: базовый синтаксис и тонкая настройка

По умолчанию, когда используется синтаксис с user@host:, rsync сам использует SSH в качестве транспорта. Однако опция -e (или --rsh) позволяет явно указать эту команду и передать ей дополнительные параметры.

Базовая команда

rsync -avz -e ssh /local/src/ user@remote-host:/remote/dest/
  • -e ssh: явное указание rsync использовать клиент SSH (ssh). Хотя это часто и так по умолчанию, явное указание полезно для читаемости или когда нужно добавить аргументы для самого SSH.

Зачем это нужно?

Настоящая польза опции -e раскрывается, когда вам нужно передать дополнительные аргументы SSH-клиенту.

Рассмотрим наиболее распространённые сценарии:

  • Указание конкретного приватного ключа: Если для подключения нужно использовать ключ, который не добавлен в ssh-agent и не стандартный (~/.ssh/id_rsa).

rsync -avz -e 'ssh -i /path/to/private_key' /src/ user@host:/dest/
  • Отключение строгой проверки хоста (для скриптов): В автоматических скриптах иногда нужно отключить запрос о добавлении хоста в known_hosts. Важно понимать, что это ослабит безопасность. Лучше использовать только в контролируемых окружениях.

rsync -avz -e 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' /src/ user@host:/dest/
  • Проброс SSH-агента: Если вам нужно использовать аутентификацию через SSH-Agent для подключения к следующему хосту (чаще используется в связке с ProxyJump).

rsync -avz -e 'ssh -A' /src/ user@host:/dest/
  • Использование прыжкового сервера (Jump Host / Bastion): Когда прямой доступ к целевому серверу (final-host) есть только через промежуточный хост (jump-host).

# "Современный" способ (требуется свежий ssh и rsync)
rsync -avz -e 'ssh -J user@jump-host:port' /src/ user@final-host:/dest/

# Классический способ с ProxyCommand
rsync -avz -e 'ssh -o ProxyCommand="ssh -W %h:%p user@jump-host"' /src/ user@final-host:/dest/

Подробнее про связку -avz -e ssh:

  • -a: архивный режим (сохраняет всё).

  • -v: подробный вывод (видно, что копируется).

  • -z: сжатие "на лету" (экономит трафик).

  • -e ssh: обеспечивает безопасное, зашифрованное соединение с удалённым хостом по SSH.

3.2. Нестандартный порт? Не проблема!

По умолчанию SSH-сервер работает на порту 22. Однако в целях безопасности (чтобы усложнить жизнь автоматическим сканерам и ботнетам) администраторы часто меняют стандартный порт на произвольный, например, на 2222, 2022, 3322 и т.д.

Если попытаться использовать rsync как обычно, он попробует подключиться к порту 22 и получит ошибку таймаута:

rsync -avz ~/data/ user@example.com:/backups/
# connection timed out
ssh: connect to host example.com port 22: Connection timed out
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(235) [sender=3.2.7]

Решение: указать нестандартный порт через -e

Чтобы сообщить rsync о необходимости использовать другой порт, мы с помощью опции -e передаём команде ssh её собственный флаг -p.

Базовый синтаксис:

rsync [ОПЦИИ] -e 'ssh -p &lt;ПОРТ&gt;' ИСТОЧНИК НАЗНАЧЕНИЕ

Практический пример: копирование данных на сервер, где SSH работает на порту 2222:

# PUSH: Отправка данных на удалённый сервер
rsync -avz -e 'ssh -p 2222' ~/data/ user@example.com:/backups/

# PULL: Забор данных с удалённого сервера
rsync -avz -e 'ssh -p 2222' user@example.com:/var/log/app/ ./logs/

Важные нюансы и варианты записи

  1. Кавычки являются обязательными. Пробел между -e и его аргументом, а также пробел внутри аргумента (ssh -p 2222) требуют, чтобы вся строка была заключена в кавычки. Это нужно для правильной интерпретации командной оболочкой (shell).

  2. Двойные или одинарные кавычки? В большинстве случаев разницы нет. Одинарные кавычки предпочтительнее, так они предотвращают преобразование чего-либо внутри них shell'ом.

  3. Комбинирование с другими опциями SSH. Флаг -p можно комбинировать с другими опциями SSH внутри одной строки. Например, указать и порт, и конкретный ключ:

rsync -avz -e 'ssh -p 2222 -i ~/.ssh/my_custom_key' ~/data/ user@example.com:/backups/

Вывод: использование -e 'ssh -p ' - это быстрое и стандартное решение для подключения к серверам с нестандартным SSH-портом. Для постоянной работы удобнее настроить ~/.ssh/config (об этом ниже).

3.3. SSH-ключи и config-файл: билет к автоматизации

Писать каждый раз полную строку с пользователем, хостом и портом - утомительно и чревато ошибками (человеческий фактор). Решение простое - настроить SSH, чтобы он работал за кулисами, делая команды rsync короткими, читаемыми и безопасными.

1. Аутентификация по ключу (вместо пароля)

Это обязательный шаг. Без него невозможно автоматизировать rsync в скриптах (например, для крон-заданий), так как некому будет вводить пароль.

Принцип работы: генерируем пару криптографических ключей (приватный и публичный). Приватный ключ остаётся у нас на клиенте, а публичный ключ копируется на удалённый сервер. SSH использует их для аутентификации вместо пароля.

Шаги по настройке:

  • Сгенерируем ключ (если его ещё нет):

ssh-keygen -t ed25519 -C "your_email@example.com"
# Или для совместимости со старыми системами: ssh-keygen -t rsa -b 4096
  • Скопируем публичный ключ на сервер:

ssh-copy-id user@remote-server

Эта команда сама добавит публичный ключ в файл ~/.ssh/authorized_keys на сервере.

  • Проверяем: теперь команда ssh user@remote-server должна подключиться без ввода пароля.

Результат для rsync: можем использовать rsync в скриптах, он не будет запрашивать пароль.

# Ранее: требует пароль каждый раз
rsync -av file.txt user@server:/path/

# После: подключается автоматически
rsync -av file.txt user@server:/path/

2. Файл ~/.ssh/config — Ваш лучший друг

Этот файл позволяет создавать алиасы (короткие имена) для серверов и хранить все настройки для них в одном месте.

В чём преимущества?

  • Короткие команды. Вместо user@very-long-server-name.example.com использовать алиас myserver.

  • Хранить настройки: порт, пользователь, пусть к ключу указываются единожды в конфиге.

  • Читаемость: команды в скриптах становятся в разы понятнее.

  • Гибкость: есть возможность легко поменять параметры подключения в одном месте.

Пример настройки ~/.ssh/config:

# Общие настройки для всех хостов
Host *
    ServerAliveInterval 60
    ServerAliveCountMax 2

# Конкретный сервер для бэкапов
Host backup
    HostName backup-server.mydomain.com
    User backupuser
    Port 2222
    IdentityFile ~/.ssh/id_backup_server

# Сервер для веб-проектов
Host prod-web
    HostName 192.168.1.100
    User deploy
    IdentityFile ~/.ssh/id_ed25519_prod

# Сервер, доступный только через Jump Host 
Host private-server
    HostName 10.0.0.5
    User admin
    ProxyJump bastion-user@bastion.mydomain.com:2222
    IdentityFile ~/.ssh/id_private_server

Как теперь будут выглядеть команды rsync?

# Было (страшно и длинно):
rsync -av -e 'ssh -p 2222 -i ~/.ssh/id_backup_server' ~/data/ backupuser@backup-server.mydomain.com:/backups/

# Стало (красиво и коротко):
rsync -av ~/data/ backup:/backups/

# Было:
rsync -av -e 'ssh -i ~/.ssh/id_ed25519_prod' ./dist/ deploy@192.168.1.100:/var/www/

# Стало:
rsync -av ./dist/ prod-web:/var/www/

# Прыжковый хост работает автоматически
rsync -av logfile.txt private-server:/logs/

Глава 4: практические кейсы и готовые рецепты

4.1. Рецепт: точное зеркало продакшена у нас на машине

Часто в работе разработчика или администратора возникает задача получить точную, актуальную копию (зеркало) работающего на продакшене веб-сайта к себе на локальную машину или на staging-сервер. Это нужно для отладки сложных багов, которые воспроизводятся только на боевом окружении, тестирования обновлений или создания резервной копии файлового содержимого.

Разберём команду для данной задачи по частям и закрепим полученный ранее материал на практике:

rsync -avz --delete user@production-server:/var/www/ /local/mirror/
  • rsync: наш основной инструмент.

  • -a (archive): основной флаг, обеспечивающий рекурсивное копирование с сохранением всех атрибутов файлов (права доступа, владелец, временные метки, симлинки). Критически важен для того, чтобы зеркало работало так же, как и оригинал.

  • -v (verbose): вывод процесса копирования. Часто очень полезно видеть, что происходит.

  • -z (compress): сжатие. Экономит трафик и время, так как файлы кода (HTML, CSS, JS, PHP) обычно очень хорошо сжимаются.

  • --delete: важнейшая опция для создания точного зеркала. Она удалит в локальной папке /local/mirror/ все файлы, которых больше нет на продакшн-сервере. Без этого флага вы будете лишь добавлять новые файлы, а удалённые на продакшене так и останутся в вашем зеркале, делая его неактуальным.

  • user@production-server:/var/www/: источник. Удалённый сервер и путь к корню веб-сайта. (Примечание: путь может отличаться, это может быть /var/www/html/, /srv/http/ и т.д.)

  • /local/mirror/: приёмник. Локальная директория, где будет создана точная копия.

Как это используется на практике?

  1. Вы можете оперативно получить актуальную копию работающего сайта к себе на машину, чтобы воспроизвести и исправить баг, который виден только на продакшене.

  2. Перед применением скриптов миграции БД или обновлений кода можно протестировать их на точной копии продакшена.

  3. Эту же логику можно использовать для синхронизации нескольких веб-серверов.

Важные замечания и "грабли" (куда без них)

  • Если мы запускаем команду не от root, все файлы на локальном зеркале будут принадлежать нашему пользователю. Это нормально для разработки, но если мы хотим позже развернуть это зеркало на другом сервере, права могут сбиться. Решение - запускать команду через sudo или использовать --usermap/--groupmap.

  • На продакшн-сервере должен быть настроен SSH-доступ по ключу для пользователя user(безусловно, для безопасности).

  • Эта команда копирует только файлы. База данных сайта (MySQL, PostgreSQL) не копируется. Её нужно бэкапить и восстанавливать отдельно.

  • Проверка перед удалением: перед первым запуском с --delete всегда делайте --dry-run.

rsync -avzn --delete user@production-server:/var/www/ /local/mirror/

Это покажет, какие файлы будут удалены локально, и убережёт от потери данных, если вы перепутали источник и приёмник (ну а вдруг... Человеческий фактор всегда имеет место быть).

Также, стоит разобрать "ответвление" от задачи. Часто нужно исключить из зеркала временные файлы или кэши, которые не имеют ценности и только тратят время и место.

rsync -avz --delete \
    --exclude='cache/' \
    --exclude='tmp/' \
    --exclude='*.log' \
    user@production-server:/var/www/ /local/mirror/

Итог: rsync -avz --delete - некий золотой стандарт для быстрого и эффективного создания точных зеркал директорий по сети, отлично подходящий для задач веб-разработки и администрирования.

4.2. Держим ноутбук и десктоп в синхроне

Обычно есть два основных сценария:

  1. Двусторонняя синхронизация: изменения на любой машине синхронизируются на другую. Для этого часто используют unison или скрипты на основе rsync с осторожностью, так как это может привести к конфликтам.

  2. Однонаправленная синхронизация: одна машина является "источником" (например, мощный десктоп, где вы делаете основную работу), а вторая - "приемником" (ноутбук, который вы берете с собой). Это более безопасный и предсказуемый подход с rsync.

Я рассмотрю однонаправленную синхронизацю, так как она проще и надежнее. Чаще всего десктоп выступает источником, а ноутбук - приемником.

Способы использования Rsync

1. Синхронизация по SSH (самый распространенный и безопасный способ)

Этот метод требует, чтобы на обеих машинах был установлен SSH-сервер (обычно уже стоит на Linux/macOS, на Windows нужно поставить, к примеру, OpenSSH Server).

Предположим:

  • Источник (desktop): desktop-user@desktop-ip:/home/desktop-user/work/

  • Приемник (laptop): /home/laptop-user/work/

Команда для копирования с десктопа на ноутбук (pull):
Выполняется на ноутбуке.

rsync -avz --progress --delete -e ssh desktop-user@desktop-ip:/home/desktop-user/work/ /home/laptop-user/work/

Команда для копирования с ноутбука на десктоп (push):
Выполняется на ноутбуке.

rsync -avz --progress --delete -e ssh /home/laptop-user/work/ desktop-user@desktop-ip:/home/desktop-user/work/

Разбор флагов:

  • -a (archive): режим архивирования. Сохраняет права доступа, временные метки, рекурсивно копирует и т.д.

  • -v (verbose): подробный вывод, чтобы видеть, что происходит.

  • -z (compress): сжатие данных при передаче по сети. Ускоряет процесс.

  • --progress: показывает прогресс для каждого файла.

  • --delete: удаляет файлы на приемнике, которых больше нет на источнике. Без этого флага вы будете копить мусор. Первый раз запустите без него, чтобы проверить, все ли работает правильно.

  • -e ssh: указание использовать SSH в качестве транспорта.

2. Синхронизация через общую файловую систему (например, NFS/SMB)

Если вы смонтировали общую сетевую папку с десктопа на ноутбук (или наоборот), то rsync можно использовать как для локальных папок.

Пример (после монтирования сетевой папки в /mnt/desktop-work):

rsync -av --progress --delete /mnt/desktop-work/ /home/laptop-user/work/

Это менее эффективно, чем прямой SSH, так как данные сначала копируются в общую папку, а потом к нам.

Заключение

Главные выводы, которые стоит вынести из этой статьи:

  1. Всегда проверяйте команду с -n (--dry-run). Это Ваш главный предохранитель от необратимых ошибок, особенно при использовании --delete.

  2. Думайте о слешах. Путь source и source/ - это два абсолютно разных сценария для rsync. Всегда чётко представляйте, что должно оказаться внутри целевой директории.

  3. Используйте SSH-ключи и файл ~/.ssh/config. Это не вопрос удобства, а основа для безопасной и автоматизированной работы.

  4. Начинайте с -a. Архивный режим - правильные настройки по умолчанию для 90% задач.

Эта статья - лишь первая ступень. Я сознательно не затрагивал:

  • Построение эффективных систем бэкапов с дедупликацией через --link-dest.

  • Сложная фильтрация файлов с помощью --include и --exclude.

  • Тонкая настройка производительности и работы с очень большими файлами.

Всё это - темы для следующих частей моего скромного руководства. Надеюсь, Вы смогли найти и узнать что-то новое в статье. На её написание ушло огромное количество времени.

P.S. В моей группе в Телеграмм разбираем практические кейсы: скрипты (Python/Bash/PowerShell), тонкости ОС и инструменты для эффективной работы.

Комментарии (0)


  1. mavir
    17.09.2025 14:41

    Еще один полезный ключ --rsync-path='sudo rsync', если требуется закинуть файлы, куда нет прав текущему пользователю, например, какие-нибудь конфиги в /etc