cp копирует файлы и (с -r) каталоги. Новая копия — отдельный файл со своим inode: изменения в ней не затрагивают оригинал. В песочнице — GNU coreutils 9.4.
Синтаксис
cp [опции] источник назначение # один файл → новое имя или в каталог
cp [опции] источник… каталог/ # несколько файлов → внутрь каталога
cp [опции] -t каталог источник… # то же, каталог первым (удобно для xargs)
cp -r [опции] каталог назначение # каталог целиком
Если назначение — существующий каталог, копия ложится внутрь него с тем же именем. Иначе создаётся (или перезаписывается) файл назначение.
Опции
Каталоги и ссылки
| Опция | Что делает |
|---|
-r, -R | копировать каталоги рекурсивно. Символические ссылки внутри копируются как ссылки |
-L | вместо ссылок копировать файлы, на которые они указывают |
-P | копировать ссылки как ссылки (с -r это и так по умолчанию) |
-H | следовать ссылкам только из командной строки |
-l | не копировать данные, а сделать жёсткие ссылки |
-s | сделать символические ссылки (источник — абсолютным путём, см. ниже) |
-x | не выходить за пределы файловой системы источника |
--parents | воссоздать путь источника внутри каталога назначения: cp --parents a/b/f out/ → out/a/b/f |
-t каталог | каталог назначения задаётся заранее, все остальные аргументы — источники |
-T | считать назначение обычным именем, даже если это существующий каталог |
Что сохранять
| Опция | Что делает |
|---|
| (по умолчанию) | владелец — тот, кто копирует; дата — текущая; права — как у источника минус umask. Если файл назначения уже был, его права и владелец не меняются |
-p | сохранить права, владельца и группу (если хватает прав), время доступа и изменения |
--preserve=СПИСОК | выборочно: mode, ownership, timestamps, links, context, xattr, all |
--no-preserve=mode | наоборот, не переносить указанное |
-a | архивный режим: -r + -P + --preserve=all. Для резервных копий и переноса каталогов «как есть» |
Перезапись
| Опция | Что делает |
|---|
-i | спрашивать перед перезаписью |
-n | не перезаписывать существующие файлы (в 9.4 печатает предупреждение о непереносимости; новая форма — --update=none) |
-u | копировать, только если источник новее назначения или назначения нет (--update=older) |
-f | если файл назначения не открыть на запись (например, у него права 444) — удалить его и создать заново |
-b | сделать резервную копию заменяемого файла (файл~); --backup=numbered — файл.~1~, файл.~2~… |
-S суффикс | суффикс резервной копии вместо ~ |
Прочее
| Опция | Что делает |
|---|
-v | печатать каждое действие: 'x' -> 'z' |
--sparse=always | делать «дырявый» файл, пропуская нули (по умолчанию auto) |
--reflink=auto | копия через CoW, если ФС умеет (btrfs, xfs), иначе обычная |
Каталог-источник: src, src/ и src/.
| Команда | dst не существует | dst уже есть |
|---|
cp -r src dst | создастся dst = копия src | появится dst/src |
cp -r src/ dst | то же самое | то же: dst/src |
cp -r src/. dst | создастся dst = копия src | содержимое src ляжет прямо в dst |
В отличие от rsync, косая черта в конце источника для cp ничего не меняет. «Содержимое каталога, а не сам каталог» — это src/..
Примеры
# резервная копия конфига рядом
cp /etc/hosts /etc/hosts.bak
# каталог целиком, с правами, владельцами, датами и ссылками
cp -a /srv/app /srv/app.backup
# содержимое каталога в уже существующий каталог
cp -a /srv/app/. /mnt/new-app/
# несколько файлов внутрь каталога, с отчётом
cp -v *.conf /etc/myapp/
# не трогать файлы, которые уже есть в назначении
cp -r --update=none defaults/. /etc/myapp/
# обновить только изменившиеся файлы
cp -ru src/. mirror/
# сохранить структуру каталогов
mkdir -p /tmp/out && cp --parents etc/app/app.conf /tmp/out/
# из find: каталог назначения задаём через -t
find . -name '*.log' -print0 | xargs -0 cp -t /tmp/logs/
# файл, имя которого начинается с дефиса
cp -- -report.txt report.txt
Подводные камни
- Без
-r каталог не копируется: «-r not specified; omitting directory». Код возврата при этом 1.
- Повторный
cp -r src dst не обновит dst, а создаст dst/src: при втором запуске dst уже существует. Для синхронизации используй src/. или rsync.
- Без
-p/-a теряются владелец и даты. Даже root, копируя чужой файл, получает файл с владельцем root и текущей датой.
- Права существующего файла не меняются.
cp в существующий файл перезаписывает только содержимое; права и владелец остаются старыми.
cp файл несуществующий_каталог/ — ошибка «Not a directory». Без косой черты тот же вызов молча создаст файл с этим именем.
- Тихая перезапись. Без
-i/-n cp перезаписывает назначение без вопросов (в интерактивной оболочке иногда есть алиас cp -i, в скриптах его нет).
-n возвращает 0, даже если ничего не скопировано, — в скрипте этого не заметишь.
cp -s с относительным источником работает, только если ссылка создаётся в текущем каталоге; иначе — «can make relative symbolic links only in current directory». Пиши источник абсолютным путём.
См. также
mv · rsync · ln · rm · tar · umask · mkdir