Rsync vs scp: какую команду копирования выбрать в Linux
Rsync против scp: rsync возобновляет передачу и копирует только изменения — scp просто копирует. Цифры скорости, нужные флаги и случаи, когда scp выигрывает.
Используйте 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, а проход контрольных сумм добавляет лишь небольшой оверхед. Разрыв открывается в трёх местах:
- Много мелких файлов. rsync конвейеризирует обход каталогов и переиспользует одно соединение; старые варианты scp создавали работу на каждый файл. Тысячи мелких файлов (тот же
node_modules, установка WordPress) rsync заканчивает заметно быстрее. - Повторные прогоны. Скопируйте файл на 4 ГБ, в котором изменилось 50 МБ, — rsync передаст примерно эти 50 МБ, scp снова 4 ГБ.
- Сжатие.
-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: он превращает каждый будущий обрыв соединения из «начать заново» в «сделать паузу».