ServerAID
Найти гайд, команду, тег… ⌘ K
Shell и скрипты

Как скопировать файл в 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.

Похожие материалы

Shell и скрипты

Как распаковать tar.gz в Linux через терминал: tar, zip, xz и другие форматы

Короткий ответ — tar -xzf archive.tar.gz. Дальше разбираем, что означает каждая буква, как распаковать в нужный каталог, посмотреть содержимое до распаковки, вытащить один файл из большого архива и не поймать «tar-бомбу», которая раскидает сотни файлов по текущему каталогу.

Редакция
Shell и скрипты

Команда lsblk в Linux: как посмотреть диски, разделы и точки монтирования

lsblk показывает все блочные устройства сервера деревом: диски, разделы, LVM-тома, шифрованные контейнеры и куда они смонтированы. Разбираем колонки вывода, флаг -f для файловых систем и UUID, свои наборы колонок через -o и типовые задачи — найти новый диск, собрать строку для fstab, понять структуру LVM.

Редакция
Shell и скрипты

Команды vi в Linux: режимы, навигация, поиск и замена — шпаргалка

Начнём с главного: выйти из vi — это Esc, затем :q! без сохранения или :wq с сохранением. Дальше — рабочий минимум команд, которого хватает для правки конфигов на сервере: режимы, перемещение, удаление и вставка, поиск с заменой и трюк для сохранения файла, который открыли без sudo.

Редакция
Shell и скрипты

Как удалить файл или каталог в Linux через терминал: rm, rmdir и безопасные привычки

Разбираем удаление в терминале: rm для файлов, rmdir для пустых каталогов, rm -r для каталогов с содержимым. Отдельно — чем опасен rm -rf, как удалить файл со странным именем, почему после удаления не освободилось место и как настроить автоочистку старых логов.

Редакция