← Весь справочник

rsync

Синхронизация каталогов локально и по SSH — копирует только изменения, умеет удалять лишнее и исключать файлы

rsync копирует файлы и каталоги так, чтобы приёмник совпал с источником. Он сравнивает размер и время изменения и передаёт только то, что отличается, а у изменённых файлов по сети — только изменённые куски. Поэтому повторный запуск почти мгновенный. Работает локально и между машинами по SSH; на удалённой стороне тоже должен быть установлен rsync.

Синтаксис

rsync [опции] источник… приёмник
rsync [опции] источник… user@host:/путь     # на удалённую машину по SSH
rsync [опции] user@host:/путь приёмник      # с удалённой машины
rsync [опции] источник                      # без приёмника — только список файлов

Слеш в конце источника

КомандаРезультат
rsync -a src dst/появится dst/src/… — копируется сам каталог
rsync -a src/ dst/появится dst/… — копируется содержимое каталога

Для каталога-источника слеш в конце приёмника ничего не меняет. А для одного файла важен: rsync -a file dst создаст файл dst, а rsync -a file dst/ — каталог dst с файлом внутри.

Что сохранять

ОпцияЧто делает
-aрежим архива = -rlptgoD: рекурсивно, ссылки, права, время, группа, владелец, устройства
-rтолько рекурсия — без прав, времени и владельцев
-Hсохранять жёсткие ссылки (в -a не входит)
-A / -Xсохранять ACL / расширенные атрибуты
-Lкопировать файлы вместо символических ссылок
-kссылки на каталоги заменять самими каталогами
--safe-linksпропускать ссылки, ведущие за пределы копируемого дерева
-xне переходить на другие файловые системы
--chown=user:groupназначить владельца в приёмнике
--chmod=D750,F640назначить права: D — каталогам, F — файлам; можно u+x, go-w
--numeric-idsпереносить UID/GID числами, не сопоставляя имена
--no-perms, --no-owner, --no-groupубрать отдельный пункт из -a

Какие файлы брать

ОпцияЧто делает
--exclude='шаблон'не копировать подходящие файлы и каталоги
--include='шаблон'копировать, даже если дальше есть подходящий --exclude
--exclude-from=файл / --include-from=файлшаблоны из файла, по одному на строку
-Fбрать правила из файлов .rsync-filter в каталогах источника
-Cпропускать то, что обычно не нужно: .git, .svn, *.o, core и т. п.
--files-from=списоккопировать только перечисленные в файле пути (относительно источника)
-Rсохранить в приёмнике путь источника целиком (src/a/b → dst/src/a/b)
-mне создавать пустые каталоги (удобно с --include/--exclude)
--max-size=100M / --min-size=1kпропускать файлы больше / меньше указанного
--existingобновлять только файлы, которые уже есть в приёмнике
--ignore-existingне трогать файлы, которые уже есть в приёмнике
-uне перезаписывать файлы, которые в приёмнике новее

Как сравнивать

ОпцияЧто делает
(по умолчанию)файл одинаковый, если совпадают размер и время изменения
-cсравнивать по контрольной сумме — медленно, но надёжно
--size-onlyсравнивать только размер
-Iпередавать даже файлы с одинаковыми размером и временем
--modify-window=1считать время одинаковым при разнице до 1 секунды (FAT, сетевые ФС)
-Wпередавать файлы целиком, без поиска изменённых кусков (быстрее локально)

Удаление и резервные копии

ОпцияЧто делает
--deleteудалить в приёмнике файлы, которых нет в источнике
--delete-afterудалять после передачи, а не до неё
--delete-excludedудалять в приёмнике и исключённые файлы
--max-delete=Nне удалять больше N файлов (защита от ошибки, код 25)
--remove-source-filesудалить из источника переданные файлы (перенос; каталоги остаются)
-bзаменяемые и удаляемые файлы сохранять с суффиксом ~
--backup-dir=каталогсохранять их в отдельный каталог
--suffix=.bakсвой суффикс для резервных копий
--link-dest=каталогнеизменённые файлы делать жёсткими ссылками на файлы в каталоге — экономные ежедневные снимки

Передача и сеть

ОпцияЧто делает
-n (--dry-run)ничего не менять, только показать, что будет сделано
-zсжимать данные при передаче по сети
-e 'ssh -p 2222 -i ~/.ssh/key'как подключаться к удалённой машине
--rsync-path='sudo rsync'какую команду запустить на удалённой стороне
--bwlimit=10mограничить скорость
-P--partial --progress: сохранять недокачанное и показывать прогресс
--partialне удалять недокачанный файл — докачать при следующем запуске
--inplaceписать прямо в файл приёмника, без временной копии
--timeout=60оборвать, если 60 секунд нет обмена данными
--mkpathсоздать недостающие каталоги пути приёмника

Вывод

ОпцияЧто делает
-vпечатать передаваемые файлы и итог
-iпечатать для каждого файла, что именно изменилось (формат ниже)
-hразмеры в человеческом виде
--progress / --info=progress2прогресс по каждому файлу / общий прогресс
--statsподробная статистика в конце
--log-file=файлписать журнал в файл
-qмолчать, кроме ошибок

Строка -i выглядит как >f.st...... путь. Первый символ — что происходит: > получено, < отправлено, c создано (каталог, ссылка), . только атрибуты, *deleting — удалено. Второй — тип: f файл, d каталог, L ссылка. Дальше буквы на месте точек — что отличалось: s размер, t время, p права, o владелец, g группа. +++++++++ — новый файл.

Коды возврата

КодЗначение
0успех
23часть файлов не передана (нет доступа, нет источника)
24часть файлов исчезла во время копирования
25сработал --max-delete
12, 255обрыв связи / ошибка SSH

Примеры

# зеркало каталога: содержимое /srv/app в /srv/backup/app
rsync -a /srv/app/ /srv/backup/app/

# сначала посмотреть, что изменится и что удалится
rsync -avn --delete /srv/app/ /srv/backup/app/

# точное зеркало с удалением лишнего
rsync -a --delete /srv/app/ /srv/backup/app/

# без логов, зависимостей и .git
rsync -a --exclude='*.log' --exclude='node_modules/' --exclude='.git/' ~/project/ /srv/app/

# только .conf, с сохранением структуры каталогов и без пустых каталогов
rsync -am --include='*/' --include='*.conf' --exclude='*' /etc/ /srv/backup/etc-conf/

# выложить на сервер по SSH со сжатием и прогрессом
rsync -azh --progress ~/project/ deploy@example.com:/srv/app/

# нестандартный порт SSH и свой ключ
rsync -az -e 'ssh -p 2222 -i ~/.ssh/deploy' ~/project/ deploy@example.com:/srv/app/

# забрать логи с сервера к себе
rsync -az deploy@example.com:/var/log/nginx/ ./nginx-logs/

# выложить с правильными владельцем и правами
rsync -a --chown=www-data:www-data --chmod=D755,F644 ./public/ /srv/app/public/

# большой файл по нестабильной сети — с докачкой
rsync -P backup.tar.gz deploy@example.com:/srv/backup/

# ежедневный снимок: неизменённые файлы — жёсткие ссылки на вчерашние
rsync -a --delete --link-dest=/srv/snap/yesterday /srv/app/ /srv/snap/today/

# показать по каждому файлу, что именно отличается
rsync -ai /srv/app/ /srv/backup/app/

Подводные камни

  • Слеш в конце источника меняет результат. src и src/ — разные команды: без слеша внутри приёмника появится лишний уровень src/. Особенно опасно вместе с --delete.
  • --delete удаляет без вопросов. Если перепутать источник с приёмником или указать не тот каталог, данные пропадут. Всегда сначала запускай с -n, а в скриптах добавляй --max-delete.
  • Исключённые файлы --delete не трогает. Файл, подпавший под --exclude, останется в приёмнике. Чтобы удалить и его, нужен --delete-excluded.
  • Шаблоны исключений. --exclude=sub исключит sub на любом уровне, --exclude=/sub — только в корне источника. Слеш в конце (node_modules/) — только каталоги.
  • Порядок --include и --exclude важен: срабатывает первое подходящее правило. Чтобы взять только *.conf, нужны --include='*/' (иначе rsync не зайдёт в подкаталоги), потом --include='*.conf', и в конце --exclude='*'.
  • Приёмник создаётся только на один уровень. rsync -a src/ /нет/такого/пути/ упадёт с «mkdir failed», если нет родительских каталогов. Создай их заранее или добавь --mkpath.
  • Без приёмника rsync ничего не копирует, а печатает список файлов, как ls -l. Забытый аргумент легко не заметить.
  • Одинаковый размер и время — «файл не изменился». Файл с другим содержимым, но тем же размером и временем изменения, rsync пропустит. Для проверки по содержимому нужен -c.
  • Владельцы сохраняются только у root. Обычный пользователь получит все файлы на себя. -a не сохраняет жёсткие ссылки — для них нужен -H.
  • На удалённой машине тоже нужен rsync. Без него соединение по SSH оборвётся с ошибкой «connection unexpectedly closed».

См. также

ssh · tar · cp · find · cron · chown · ln