Rsync vs scp: какую команду копирования выбрать в Linux

Rsync против scp: rsync возобновляет передачу и копирует только изменения — scp просто копирует. Цифры скорости, нужные флаги и случаи, когда scp выигрывает.

HUMANавтор @mrsaynothing48d5 мин чтения

Используйте rsync для всего, что больше быстрой разовой копии, и scp — когда файл просто нужен на другой машине прямо сейчас. Ключевая разница: scp каждый раз передаёт файл целиком и не помнит об оборвавшемся соединении, а rsync сверяет источник с приёмником, передаёт только изменённые блоки и продолжает прерванное копирование с места остановки. На большом бэкапе по ненадёжному каналу это разница между «две минуты» и «начинай сначала». Оба инструмента входят в OpenSSH практически любого дистрибутива Linux, так что это выбор привычки, а не установки, — и привычка должна быть в пользу rsync. Ниже: честная таблица сравнения, реальная разница в скорости, трюк с возобновлением, которого scp не умеет, и случаи, когда scp всё же правильный ответ.

В чём разница между rsync и scp?

scp делает одну вещь: открыть SSH-канал, передать байты, закрыть. Между запусками у неё нет состояния, поэтому если передача умерла на 90%, вы начинаете с нуля.

rsync — инструмент синхронизации, который лишь попутно использует SSH как транспорт. Перед отправкой он строит список контрольных сумм файла-приёмника (дельта-алгоритм с rolling checksum) и передаёт только различающиеся блоки. Запустите ту же команду дважды — второй проход почти ничего не передаст. Это же делает rsync естественным инструментом для синхронизации двух каталогов: поставьте его на расписание, и каждый прогон копирует одни дельты.

Практические следствия:

  • Прерывания: rsync возобновляет; scp начинает файл заново.
  • Повторные копии: rsync передаёт только изменения; scp шлёт всё снова.
  • Удаления: rsync умеет зеркалировать удаления через --delete; scp — нет.
  • Фильтрация: у rsync есть шаблоны --exclude; scp копирует всё, на что вы указали.
  • Пробные прогоны: rsync показывает, что сделает, через --dry-run; scp не предлагает ничего.

Rsync быстрее scp?

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

  1. Много мелких файлов. rsync конвейеризирует обход каталогов и переиспользует одно соединение; старые варианты scp создавали работу на каждый файл. Тысячи мелких файлов (тот же node_modules, установка WordPress) rsync заканчивает заметно быстрее.
  2. Повторные прогоны. Скопируйте файл на 4 ГБ, в котором изменилось 50 МБ, — rsync передаст примерно эти 50 МБ, scp снова 4 ГБ.
  3. Сжатие. -z жмёт в полёте — помогает на медленных WAN-каналах.

Можно замерить и самому — команды одинаковые по форме:

# тот же файл, тот же сервер, оба поверх SSH
time scp bigfile.tar.gz user@server:/tmp/
time rsync -avh --progress bigfile.tar.gz user@server:/tmp/

# прогоните оба снова: scp перекопирует, rsync сверит и не передаст почти ничего
time scp bigfile.tar.gz user@server:/tmp/
time rsync -avh --progress bigfile.tar.gz user@server:/tmp/

Если ваш день проходит в серверах, скорость передачи — из тех вещей, которые стоит замерить один раз, — так же как ss обходит netstat на нагруженных хостах (см. ss vs netstat: какую команду для портов использовать).

Может ли scp возобновить прерванную передачу?

Нет. У scp нет возобновления: если соединение упало на 900 МБ из 1 ГБ, вы начинаете сначала. Это самый цитируемый аргумент в любом споре rsync против scp, и он настоящий.

Весь дизайн rsync исходит из того, что передачу иногда будут рвать. Каноничное заклинание возобновления:

rsync -avh --partial --append-verify --progress bigfile.tar.gz user@server:/srv/backup/
  • --partial сохраняет недописанный файл вместо того, чтобы удалять его.
  • --append-verify возобновляет передачу дописыванием, а затем проверяет контрольными суммами добавленную область — безопасно при битом частичном файле, в отличие от старого простого --append.
  • --progress показывает, с какого места он подхватил.

Завёрнутое в цикл повторов, это бэкап «поставил и забыл» даже по враждебному соединению:

until rsync -avh --partial --append-verify --progress \
    ./bigfile.tar.gz user@server:/srv/backup/; do
  sleep 5
done

Когда вместо rsync стоит использовать scp?

scp остаётся правильным инструментом в нескольких случаях:

  • Один маленький файл, один раз. Набрать scp app.conf user@host:/etc/myapp/ короче, чем любой вызов rsync, а возобновлять нечего.
  • На дальнем конце нет rsync. rsync требует своего бинарника с обеих сторон. Во многих минимальных контейнерах и прошивках есть SFTP-сервер scp, но нет rsync.
  • Вы не хотите торчащий наружу rsync-сервер. Редкость, но некоторые окружения отдельно закрывают rsync-демон.

Тонкость, которую стоит знать: проект OpenSSH много лет назад объявил устаревшим оригинальный протокол scp, и современный scp внизу говорит на SFTP. Это починило один причудливый баг с экранированием путей, но не изменило двух ограничений, которые здесь важны, — ни возобновления, ни дельта-передачи. Смена протокола не делает scp rsync'ом.

Рядом и вопрос «rsync vs cp»: ответ зеркален этому — cp — локальный аналог scp (без возобновления, без дельт, без атрибутов, пока не добавите флаги), а rsync работает и локально, и по сети. Для локальных разовых копий cp вполне годится.

Какие флаги rsync важнее всего?

Большинству людей хватает одной строки:

rsync -avh --partial --progress src/ user@server:/srv/dest/
Флаг Что делает
-a (archive) Рекурсивно + сохраняет права, времена, группу, симлинки, устройства
-v (verbose) Перечисляет, что передаёт
-h (human) Человекочитаемые размеры
--partial Сохраняет недопереданные файлы, чтобы повторный запуск продолжил
--progress Прогресс по каждому файлу — то, чего у scp никогда не было
-z Сжимает в полёте (медленный CPU на быстрой LAN: пропустите)
--delete Зеркалит и удаления — опасно, всегда сначала сухой прогон
--dry-run (-n) Показывает, что будет сделано, ничего не меняя

Две привычки, которые стоит завести. Первая — сухой прогон для всего, что содержит --delete:

rsync -avh --delete --dry-run src/ user@server:/srv/dest/   # смотрим
rsync -avh --delete src/ user@server:/srv/dest/             # затем выполняем

Вторая — следите за завершающим слэшем: /srv/src копирует сам каталог в приёмник, а /srv/src/ — его содержимое. На этом спотыкаются все хотя бы раз; rsync даже предупредит «no bytes transferred», когда вы имели в виду другую форму.

Для ежедневной или еженедельной синхронизации положите rsync в systemd-таймер и позвольте ему передавать одни дельты — стороне с журналами планирования посвящена шпаргалка по journalctl.

Rsync vs scp: вердикт

scp rsync
Входит в OpenSSH Да Да (нужен на обеих сторонах)
Возобновление прерванной передачи Нет Да (--partial)
Дельта-передача при повторах Нет Да
Сохранение прав/симлинков Частично Полностью (-a)
Шаблоны исключений Нет --exclude
Сухой прогон Нет --dry-run
Зеркалирование удалений Нет --delete
Лучше всего для Быстрых разовых копий Бэкапов, синхронизаций, больших деревьев

По умолчанию — rsync: бэкапы, большие деревья, всё, что идёт по каналу, который может оборваться, и всё, что вы запустите больше одного раза. scp — когда команда короче мысли. Если унести с собой один флаг, берите --partial: он превращает каждый будущий обрыв соединения из «начать заново» в «сделать паузу».