Как скопировать файл в Linux через терминал: cp, rsync и scp с примерами
Разбираем копирование в терминале: cp для файлов и каталогов, флаг -a для сохранения прав и симлинков, rsync для больших объёмов и докачки, scp для переноса на другой сервер. Плюс ловушки со слэшем в конце пути и скрытыми файлами, на которых теряют данные.
Копирование в терминале выглядит просто ровно до первого случая, когда права на скопированных файлах слетели, симлинки превратились в обычные файлы, а половина содержимого каталога не доехала. Разбираем cp со всеми нужными флагами, rsync для серьёзных объёмов и scp для переноса между серверами.
cp: базовые случаи
Копирование файла в другой файл:
cp report.txt report-backup.txt
Копирование в каталог с сохранением имени:
cp report.txt /var/backups/
Несколько файлов сразу — последним аргументом всегда идёт каталог назначения:
cp access.log error.log debug.log /var/backups/
По маске:
cp *.conf /etc/myapp/
Если файл назначения существует, cp молча его перезапишет. Спросить подтверждение:
cp -i report.txt /var/backups/
Не перезаписывать существующие вообще:
cp -n report.txt /var/backups/
Копировать только если исходный новее — удобно для синхронизации конфигов:
cp -u report.txt /var/backups/
Показывать, что происходит:
cp -v *.conf /etc/myapp/
Сделать резервную копию перед перезаписью:
cp --backup=numbered new.conf /etc/app.conf
# старый файл станет app.conf.~1~
Копируем каталог
Для каталога нужен рекурсивный режим:
cp -r project/ /var/www/
Здесь прячется главная ловушка — слэш в конце источника. Поведение зависит от того, существует ли каталог назначения:
cp -r src /tmp/dst # если /tmp/dst нет — создастся копия с именем dst
# если /tmp/dst есть — получится /tmp/dst/src
Чтобы копировать содержимое, а не сам каталог, указывают точку:
cp -r src/. /tmp/dst/
Запись src/. означает «всё внутри src, включая скрытые файлы». Именно она нужна, когда копируете конфиги приложения и не хотите потерять .env.
Вариант cp -r src/* dst/ работает иначе: маску * раскрывает шелл, а он не включает файлы, начинающиеся с точки. Так теряют .env, .git и .htaccess — и обнаруживают это позже.
Проверить, что попадёт под маску, до копирования:
echo src/*
ls -a src/
Сохраняем права, владельца и время
Обычный cp создаёт файлы от вашего имени с текущим временем и правами по umask. Для бэкапа или переноса системных каталогов это неприемлемо.
Флаг -p сохраняет права, владельца и метки времени:
cp -p /etc/nginx/nginx.conf /var/backups/
Флаг -a (archive) — то, что нужно в большинстве серьёзных случаев:
sudo cp -a /var/www/site /var/backups/site-2026-08-12
-a эквивалентен -dR --preserve=all, то есть:
- рекурсивно обходит каталоги;
- сохраняет права, владельца, группу, метки времени;
- копирует симлинки как симлинки, а не как файлы, на которые они указывают;
- сохраняет ACL и расширенные атрибуты.
Разница между -r и -a на симлинках наглядно видна так:
ln -s /etc/hostname link
cp -r link /tmp/ # в /tmp/link окажется содержимое /etc/hostname
cp -a link /tmp/ # в /tmp/link окажется симлинк
Для копирования системных каталогов используйте sudo cp -a, иначе владельцем всех файлов станет ваш пользователь. Про владельцев подробно — в статье про chown.
Отдельный флаг для больших разрежённых файлов (образов дисков, файлов подкачки):
cp --sparse=always disk.img /backup/
Без него разрежённый файл на 100 ГБ, реально занимающий 2 ГБ, займёт при копировании все 100.
rsync: большие объёмы и докачка
cp не умеет продолжать прерванное копирование и каждый раз копирует всё заново. rsync передаёт только различия и переживает обрыв.
rsync -a --info=progress2 /var/www/ /mnt/backup/www/
Флаг -a здесь означает то же, что у cp: рекурсивно, с сохранением прав, владельца, времени и симлинков. --info=progress2 показывает общий прогресс по всей операции.
Слэш в конце источника у rsync значит строго определённое:
rsync -a /var/www/ /mnt/backup/ # содержимое www попадёт в backup
rsync -a /var/www /mnt/backup/ # получится /mnt/backup/www
Это самая частая ошибка при работе с rsync, и в отличие от cp тут поведение не зависит от существования каталога назначения — только от слэша.
Зеркальная синхронизация с удалением лишнего:
rsync -a --delete /var/www/ /mnt/backup/www/
--delete удаляет в приёмнике то, чего больше нет в источнике. Опасный флаг: при ошибке в путях он вычистит нужные данные. Всегда прогоняйте сначала вхолостую:
rsync -a --delete --dry-run --itemize-changes /var/www/ /mnt/backup/www/
--dry-run ничего не меняет, --itemize-changes печатает список планируемых действий. Полный разбор ключей и сценариев бэкапа — в статье про rsync.
Копируем на другой сервер
Через scp — синтаксис как у cp, но с адресом хоста:
scp report.txt user@192.168.1.10:/home/user/
scp user@192.168.1.10:/var/log/app.log ./
scp -r project/ user@192.168.1.10:/var/www/
Нестандартный порт SSH указывается заглавной -P (в отличие от строчной -p у ssh):
scp -P 2222 report.txt user@192.168.1.10:/home/user/
Для больших объёмов лучше rsync поверх SSH — он докачивает после обрыва:
rsync -a --info=progress2 -e "ssh -p 2222" /var/www/ user@192.168.1.10:/var/www/
Обе команды требуют аутентификации; чтобы не вводить пароль каждый раз, настройте SSH-ключи.
Копирование напрямую между двумя удалёнными хостами:
scp user1@host1:/path/file user2@host2:/path/
По умолчанию трафик пойдёт через вашу машину; флаг -3 явно включает такое поведение, если прямое соединение между хостами невозможно.
Копирование с правами за один шаг
Когда файл нужно положить с конкретными правами и владельцем, install делает это одной командой:
sudo install -m 644 -o root -g root app.conf /etc/myapp/app.conf
sudo install -m 755 deploy.sh /usr/local/bin/deploy
sudo install -d -m 750 -o www-data /var/www/private
Флаг -d создаёт каталог. Такой подход удобен в скриптах развёртывания: не нужно помнить про отдельный chmod после копирования, и нет окна, когда файл лежит с неправильными правами. Числовые режимы разобраны в статье про chmod.
Прогресс при копировании
У cp в свежих версиях coreutils есть собственный индикатор:
cp --progress bigfile.img /mnt/backup/
Универсальный способ — утилита pv:
sudo apt install pv
pv bigfile.img > /mnt/backup/bigfile.img
Она показывает скорость, объём и оценку оставшегося времени. Посмотреть прогресс уже запущенного cp в соседнем терминале:
sudo apt install progress
progress -m
Проверяем результат
Сравнить два файла побайтово:
cmp original.img copy.img && echo "идентичны"
Сравнить каталоги:
diff -r src/ dst/
Проверить контрольные суммы после переноса по сети:
sha256sum original.iso
sha256sum /mnt/backup/original.iso
Быстрая сверка через сам rsync — если он не находит различий, вывод будет пустым:
rsync -a --dry-run --itemize-changes src/ dst/
Убедиться, что права доехали:
ls -l /var/backups/site
stat /var/backups/site/index.html
Частые вопросы
Как скопировать каталог со всем содержимым?
Командой cp -r источник назначение. Для бэкапов и системных каталогов лучше cp -a — она дополнительно сохраняет права, владельца, метки времени и симлинки.
Если каталог большой или копирование может прерваться, используйте rsync -a — он продолжит с места обрыва вместо повторного копирования всего.
Чем cp -r отличается от cp -a?
-r копирует рекурсивно, но права выставляются по вашему umask, владельцем становится текущий пользователь, время — текущее, а симлинки разыменовываются в обычные файлы.
-a сохраняет всё перечисленное как в оригинале. Для бэкапа, переноса /etc или каталогов сайта нужен именно -a, причём под sudo.
Почему при копировании потерялись скрытые файлы?
Потому что использовалась маска: cp -r src/* dst/. Раскрытие * делает шелл, а он не включает имена, начинающиеся с точки, — .env, .git, .htaccess остаются на месте.
Копируйте содержимое через точку: cp -a src/. dst/. Либо копируйте каталог целиком: cp -a src dst.
Как скопировать файл на другой сервер через терминал?
scp файл user@хост:/путь/ для разовой передачи. Нестандартный порт задаётся заглавной -P.
Для больших объёмов и повторяющихся задач лучше rsync -a -e ssh: он передаёт только изменения и корректно продолжает после обрыва связи.
Как скопировать файл с сохранением прав и владельца?
cp -a (или cp -p для одиночного файла), обязательно под sudo — без прав root сменить владельца скопированного файла невозможно, и владельцем станет тот, кто запустил команду.
Если файл нужно положить с заранее известными правами, а не с исходными, удобнее install -m 644 -o root -g root источник назначение.
Что запомнить
cp -r— каталог,cp -a— каталог с сохранением прав, владельца, времени и симлинков; для системных файлов нужен именно-aподsudo.cp -r src/* dst/теряет скрытые файлы. Правильно —cp -a src/. dst/.- У
rsyncслэш в конце источника меняет смысл команды:src/копирует содержимое,src— сам каталог. --deleteу rsync всегда сначала прогоняйте с--dry-run --itemize-changes.- Разовый перенос между серверами —
scp(порт через заглавную-P), большие и повторяемые —rsyncповерх SSH.