Я уже несколько лет копирую файлы с помощью команды cp, и если приходилось переносить резервную копию объемом 50 ГБ или синхронизировать дерево каталогов с удалённым сервером, эта привычка обходится мне потерей времени, контроля над процессом и возможности восстановления данных.
Команда cp отлично справляется ровно с одной задачей: она копирует файлы, но не предоставляет индикатора хода выполнения, не поддерживает ограничение скорости, не позволяет возобновлять прерванные процессы и не имеет встроенной проверки контрольных сумм.
Для локальной копии объемом в несколько мегабайт это нормально, но как только вы начинаете передавать дамп базы данных размером 40 ГБ по сети или копировать 200 000 небольших файлов на новый диск, вам понадобится нечто большее, чем мигающий курсор.
Почему cp не справляется с большими копиями
cp — это стандарт POSIX, поэтому он всегда доступен, но он был создан для простоты, а не для массовых операций с данными. Он считывает файл и записывает его последовательно, без параллелизма, без дельта-логики и без обратной связи с терминалом.
Если процесс прерывается, например, из-за отключения питания, таймаута SSH или случайного Ctrl + C, вам придется начинать сначала, потому что возобновления нет.
А если вы копируете на удаленный хост, вы делаете это через отдельную программу – scp, который ведет себя по принципу «все или ничего» и добавляет накладные расходы на шифрование, даже если вам это не нужно в собственной локальной сети.
Если вы регулярно перемещаете большие наборы данных между серверами и все еще используете cp, поделитесь этим со своей командой — приведенные ниже инструменты избавят кого-то от необходимости переделывать работу в 2 часа ночи.
rsync: незаменимый инструмент для возобновляемой передачи файлов
Rsync — это первый инструмент, который стоит освоить, когда cp недостаточно, поскольку он копирует только различия между источником и местом назначения, поддерживает возобновление и работает как локально, так и через SSH.
Установите его, если он еще не установлен:
sudo apt install rsync [On Debian, Ubuntu and Mint] sudo dnf install rsync [On RHEL/CentOS/Fedora and Rocky/AlmaLinux] sudo apk add rsync [On Alpine Linux] sudo pacman -S rsync [On Arch Linux] sudo zypper install rsync [On OpenSUSE] sudo pkg install rsync [On FreeBSD]
Префикс sudo запускает команду с правами root, что необходимо для установки пакетов. Для простого копирования локальных файлов sudo не понадобится, но для синхронизации системных каталогов он будет необходим.
Стандартное копирование локального каталога выглядит так:
rsync -av --progress /source/directory/ /destination/directory/
Вывод:
sending incremental file list
database/
database/dump_2024.sql
2,147,483,648 100% 98.45MB/s 0:00:20 (xfr#1, to-chk=0/2)
sent 2,147,483,909 bytes received 35 bytes 102.24MB/s total size is 2,147,483,648
Разбор флагов:
-aвключает режим архивирования, который сохраняет права доступа, временные метки, символьные ссылки и рекурсивную структуру каталогов с помощью одного флага.-vвыводит имя каждого файла по мере его передачи.--progressпоказывает текущую скорость передачи и процент выполнения для каждого файла.
Косая черта после /source/directory/ имеет значение: с косой чертой rsync копирует содержимое каталога. Без него rsync копирует сам каталог в качестве подкаталога внутри папки назначения. Если вы ошибетесь, то вместо ожидаемого результата получите /destination/directory/directory/ — это типичная ошибка новичков.
Для копирования на удаленный сервер по SSH синтаксис практически идентичен:
rsync -av --progress /local/path/ user@remote-ip:/remote/path/
Замените remote-ip на IP-адрес вашего сервера, который можно узнать с помощью команды ip a.
ip a
Если передача прервется на полпути, запустите ту же команду снова, и rsync продолжит с того места, где остановился, пропуская файлы, которые уже были успешно перенесены.
pv: Добавление индикаторов прогресса к передаче файлов
pv (Pipe Viewer) — это небольшая утилита, которая работает внутри конвейера Unix и показывает скорость передачи, прошедшее время и предполагаемое время завершения. Она не заменяет cp или rsync, но обертывает их.
Установите её:
sudo apt install pv [On Debian, Ubuntu and Mint] sudo dnf install pv [On RHEL/CentOS/Fedora and Rocky/AlmaLinux] sudo apk add pv [On Alpine Linux] sudo pacman -S pv [On Arch Linux] sudo zypper install pv [On OpenSUSE] sudo pkg install pv [On FreeBSD]
Самый простой способ использования — копирование одного большого файла с индикатором прогресса в реальном времени:
pv /source/large-file.iso > /destination/large-file.iso
Вывод:
8.35GiB 0:01:22 [ 104MiB/s] [=====> ] 63% ETA 0:00:47
Этот вывод точно показывает, с какой скоростью диск фактически записывает данные, чего вы никогда не получите от простого cp. Вы также можете подключить pv к сжатию для архивирования и копирования за один раз:
pv /source/large-file.tar | gzip > /destination/large-file.tar.gz
Разбор конвейера:
pv /source/large-file.tarсчитывает исходный файл и выводит пропускную способность в терминал.gzipсжимает поток в реальном времени.> /destination/large-file.tar.gzзаписывает сжатый вывод в место назначения.
dd: мощный инструмент для клонирования дисков и создания необработанных копий
dd — это низкоуровневый инструмент, который уже установлен в каждой системе Linux. Он считывает и записывает необработанные блоки, что делает его подходящим инструментом для клонирования всего диска или раздела, создания образов дисков и тестирования пропускной способности необработанного диска.
Риск при использовании dd заключается в том, что опечатка в пути вывода может привести к стиранию не того диска без предупреждения, поэтому всегда дважды проверяйте цель перед запуском.
Типичный клонирование с диска на диск выглядит так:
sudo dd if=/dev/sda of=/dev/sdb bs=64K conv=noerror,sync status=progress
Вывод:
50033664512 bytes (50 GB, 47 GiB) copied, 623.847 s, 80.2 MB/s
Разбор флагов:
if=/dev/sdaзадает входной файл, который является исходным диском.of=/dev/sdbзадает выходной файл, который является целевым диском; перед запуском обязательно убедитесь, что это правильное устройство, с помощью lsblk.bs=64Kустанавливает размер блока в 64 килобайта, что значительно быстрее, чем размер блока по умолчанию в 512 байт, при чтении больших последовательных блоков.conv=noerror,syncуказываетddпродолжать работу после ошибок чтения и заполнять поврежденные блоки нулями, а не останавливать всю копию.status=progressвыводит текущую пропускную способность каждые несколько секунд; эта функция была добавлена в coreutils 8.24 — на более старых системах у вас не будет этого флага, и вам нужно будет вручную отправить сигнал USR1, чтобы получить отчет о ходе работы.
Предупреждение: dd не запрашивает подтверждения. Если вы поменяете местами if и of, вы запишете исходный диск на целевой и уничтожите данные, которые собирались скопировать.
parallel rsync: более быстрое копирование миллионов мелких файлов
rsync работает быстро с большими файлами, но выполняет передачу в одном потоке. Если у вас есть каталог с сотнями тысяч маленьких файлов — например, каталог node_modules Node.js, почтовый спул или библиотека фотографий — rsync может занять гораздо больше времени, чем ожидалось, потому что накладные расходы на каждый файл преобладают над фактическим временем передачи данных.
Parallel решает эту проблему, запуская несколько заданий rsync одновременно.
sudo apt install parallel [On Debian, Ubuntu and Mint] sudo dnf install parallel [On RHEL/CentOS/Fedora and Rocky/AlmaLinux] sudo apk add parallel [On Alpine Linux] sudo pacman -S parallel [On Arch Linux] sudo zypper install parallel [On OpenSUSE] sudo pkg install parallel [On FreeBSD]
Затем запустите параллельный rsync по большому дереву каталогов:
find /source/directory -mindepth 1 -maxdepth 1 -type d | \
parallel -j 4 rsync -a {} /destination/directory/
Разбиваем конвейер:
find /source/directory -mindepth 1 -maxdepth 1 -type dперечисляет подкаталоги верхнего уровня источника.parallel -j 4запускает 4 задания rsync одновременно, по одному на подкаталог, поэтому настройте-jв соответствии с количеством ядер вашего процессора и скоростью диска.rsync -a {} /destination/directory/синхронизирует каждый подкаталог с местом назначения, при этом{}заменяется именем каждого каталога.
В каталоге с 500 000 небольших файлов этот подход обычно сокращает время копирования на 60–70 процентов по сравнению с одним вызовом rsync, поскольку очередь ввода-вывода остается заполненной, а не ожидает по одному файлу за раз.
Проверка целостности файлов с помощью контрольных сумм SHA256
Ни один из этих инструментов не имеет большого значения, если вы не проверите, действительно ли копирование прошло успешно. Для любого критически важного копирования запускайте сравнение контрольных сумм после завершения передачи.
SHA256 — правильный выбор для большинства целей:
sha256sum /source/large-file.iso /destination/large-file.iso
Вывод:
a3b4c1d2e5f6... /source/large-file.iso a3b4c1d2e5f6... /destination/large-file.iso
Если оба хеша совпадают, копирование прошло без ошибок. Если они различаются, во время передачи произошла ошибка, например, сбой диска, повреждение сети или конфликт с другим процессом, записывающим в исходный файл, и вам нужно скопировать файлы заново, прежде чем доверять этим данным.
Заключениеcp подходит для перемещения конфигурационного файла из одного каталога в другой, но для реальной работы системного администратора, например, для больших резервных копий, удаленной синхронизации, клонирования дисков и каталогов с миллионами инодов.
Вам необходимо использовать rsync, который обеспечивает возобновление и дельта-передачу, pv — видимость, dd — контроль на уровне блоков, а параллельный rsync — пропускную способность при работе с каталогами, наполненными мелкими файлами.
Лучшее, что можно попробовать прямо сейчас: выберите большой каталог в вашей системе и скопируйте его один раз с помощью cp, затем еще раз с помощью rsync -av --progress, и сравните результаты и время выполнения. Вы сразу увидите, чего вам не хватало, и с этого момента начнет формироваться навык работы с rsync.
Комментарии (2)