# cp — Copy Files and Directories

> Practical guide to cp: copy files and directories, preserve attributes, control overwriting, make backups, and use fast reflink copies.

Source: https://www.jpkc.com/db/en/cheatsheets/files-text/cp/

<!-- PROSE:intro -->
`cp` (copy) is one of the most fundamental Unix commands: it duplicates files and directories, creates backups, and deploys content across the filesystem. Day to day you reach for it to snapshot a config file before editing, copy a project tree recursively with `-r`, or make an exact clone with `-a`, preserving permissions, ownership and timestamps. One important pitfall: without `-i`, `cp` overwrites existing destination files silently – when in doubt, use `-i` (prompt), `-n` (never overwrite) or `-b` (keep a backup). On modern filesystems such as Btrfs or XFS, `--reflink` makes copies practically instant.
<!-- PROSE:intro:end -->

## Basic Copying

`cp <source> <destination>` — Copy a file to a new location or name.

```bash
cp config.yml config-backup.yml
```

`cp <file1> <file2> <directory>` — Copy multiple files into a directory.

```bash
cp index.html style.css app.js /var/www/html/
```

`cp <source> <directory>/` — Copy a file into a directory, keeping the original filename.

```bash
cp report.pdf /tmp/
```

`cp *.txt <directory>` — Copy all files matching a glob pattern into a directory.

```bash
cp *.jpg /backup/photos/
```

## Directory Copying

`cp -r <source_dir> <destination_dir>` — Copy a directory recursively including all contents.

```bash
cp -r ./project/ /backup/project/
```

`cp -R <source_dir> <destination_dir>` — Synonym for -r. Copy directories recursively.

```bash
cp -R ./src/ /backup/src/
```

`cp -r <source_dir>/ <destination_dir>/` — Copy the contents of a directory into another directory.

```bash
cp -r ./dist/ /var/www/html/
```

`cp -r <dir1> <dir2> <dir3> <target_dir>` — Copy multiple directories into a target directory.

```bash
cp -r ./css ./js ./images /var/www/html/
```

## Preserving Attributes

`cp -p <source> <destination>` — Preserve file mode, ownership, and timestamps.

```bash
cp -p script.sh /usr/local/bin/
```

`cp -a <source> <destination>` — Archive mode. Same as -dR --preserve=all. Preserves everything including symlinks.

```bash
cp -a /var/www/html/ /backup/www/
```

`cp --preserve=mode,timestamps <source> <destination>` — Preserve specific attributes only.

```bash
cp --preserve=mode,timestamps deploy.sh /usr/local/bin/
```

`cp --preserve=all <source> <destination>` — Preserve all attributes: mode, ownership, timestamps, context, links, xattr.

```bash
cp --preserve=all important.conf /etc/app/
```

`cp --no-preserve=ownership <source> <destination>` — Copy but explicitly do not preserve ownership.

```bash
cp --no-preserve=ownership /root/config.yml /home/user/
```

## Overwrite Control

`cp -i <source> <destination>` — Interactive mode. Prompt before overwriting an existing file.

```bash
cp -i new-config.yml /etc/app/config.yml
```

`cp -n <source> <destination>` — No clobber. Never overwrite an existing file.

```bash
cp -n defaults.conf /etc/app/config.conf
```

`cp -f <source> <destination>` — Force. Remove destination file if it cannot be opened, then copy.

```bash
cp -f updated.bin /usr/local/bin/app
```

`cp -u <source> <destination>` — Update. Only copy when source is newer than destination or destination is missing.

```bash
cp -u *.html /var/www/html/
```

`cp --update=none <source> <destination>` — Explicit update mode: none (same as -n), all (default), or older (same as -u).

```bash
cp --update=older ./assets/* /var/www/assets/
```

## Symlinks & Special Files

`cp -d <source> <destination>` — Copy symbolic links as links, not the files they point to.

```bash
cp -d current-release /backup/current-release
```

`cp -L <source> <destination>` — Always follow symbolic links. Copy the file the symlink points to.

```bash
cp -L /etc/alternatives/editor ./editor-backup
```

`cp -P <source> <destination>` — Never follow symbolic links. Copy the symlink itself (default for -r).

```bash
cp -P link.txt /backup/
```

`cp -s <source> <destination>` — Create a symbolic link instead of copying the file.

```bash
cp -s /opt/app/config.yml /etc/app/config.yml
```

`cp -l <source> <destination>` — Create a hard link instead of copying. Saves disk space.

```bash
cp -l large-file.iso /backup/large-file.iso
```

## Verbosity & Feedback

`cp -v <source> <destination>` — Verbose mode. Print each file as it is copied.

```bash
cp -v *.conf /etc/app/
```

`cp -rv <source_dir> <destination_dir>` — Recursively copy with verbose output. Shows every file being copied.

```bash
cp -rv ./project/ /backup/project/
```

`cp -v --backup=numbered <source> <destination>` — Create numbered backups of existing files and show output.

```bash
cp -v --backup=numbered config.yml /etc/app/config.yml
```

## Backup Options

`cp -b <source> <destination>` — Create a backup of the destination file (appends ~ suffix) before overwriting.

```bash
cp -b new.conf /etc/app/app.conf
```

`cp --backup=numbered <source> <destination>` — Create numbered backups (.~1~, .~2~, etc.) instead of a single ~ backup.

```bash
cp --backup=numbered config.yml /etc/app/config.yml
```

`cp --backup=existing <source> <destination>` — Use numbered backups if any already exist, otherwise use simple ~ backup.

```bash
cp --backup=existing data.json /var/data/data.json
```

`cp -S '<suffix>' <source> <destination>` — Use a custom suffix for backup files instead of the default ~.

```bash
cp -b -S '.bak' config.yml /etc/app/config.yml
```

## Sparse Files & Performance

`cp --sparse=auto <source> <destination>` — Auto-detect and preserve sparse files (default behavior).

```bash
cp --sparse=auto disk.img /backup/
```

`cp --sparse=always <source> <destination>` — Always try to create sparse files. Useful for disk images and virtual disks.

```bash
cp --sparse=always vm-disk.qcow2 /backup/
```

`cp --reflink=auto <source> <destination>` — Use copy-on-write if the filesystem supports it (Btrfs, XFS). Instant copies.

```bash
cp --reflink=auto large-file.tar /backup/
```

`cp --reflink=always <source> <destination>` — Force copy-on-write. Fails if filesystem does not support it.

```bash
cp --reflink=always database.db /snapshot/
```

## Target Directory & Structure

`cp -t <directory> <file1> <file2>` — Specify the target directory first. Useful with xargs and find.

```bash
find . -name '*.log' -print0 | xargs -0 cp -t /backup/logs/
```

`cp -T <source> <destination>` — Treat destination as a normal file, not a directory. Fails if destination is a directory.

```bash
cp -T config-new.yml config.yml
```

`cp --parents <source> <destination>` — Preserve the full source path structure under the destination directory.

```bash
cp --parents src/app/main.js /backup/
```

## Common Patterns

`cp -a <source>/ <destination>/` — Mirror a directory tree preserving all attributes. Best for local backups.

```bash
cp -a /var/www/html/ /backup/www/
```

`cp -rn <source>/ <destination>/` — Copy new files only, skip existing. Useful for incremental merges.

```bash
cp -rn ./new-assets/ /var/www/assets/
```

`cp -ru <source>/ <destination>/` — Copy only newer or missing files recursively.

```bash
cp -ru ./updated-site/ /var/www/html/
```

`cp -av <source>/ <destination>/` — Archive copy with verbose output. See exactly what gets copied.

```bash
cp -av /home/user/ /backup/user/
```

`cp /dev/null <file>` — Truncate a file to zero bytes (empty it) without deleting it.

```bash
cp /dev/null /var/log/app.log
```

`find <dir> -name '<pattern>' -exec cp {} <dest>/ \;` — Find files by pattern and copy them to a single destination directory.

```bash
find ./project/ -name '*.pdf' -exec cp {} /backup/pdfs/ \;
```

`find <dir> -name '<pattern>' -print0 | xargs -0 cp -t <dest>/` — Find and copy files safely (handles filenames with spaces).

```bash
find ./docs/ -name '*.md' -print0 | xargs -0 cp -t /backup/docs/
```

<!-- PROSE:outro -->
## Conclusion

`cp` is the workhorse for duplicating files: for everyday use, `cp <source> <destination>`, `cp -r` for directories and `cp -a` for exact mirrors with all attributes cover most needs. Keep in mind that without `-i`, `cp` overwrites existing destination files silently – when handling important data, `-i`, `-n` or `-b` are worth the keystrokes. Copy first, then modify the original is a good habit. On copy-on-write filesystems, `--reflink=auto` saves both time and space, and for large local backups `cp -a` is usually the right choice.

## Further Reading

- [GNU Coreutils: cp](https://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html) – the official reference for every option
- [cp(1) manual page](https://man7.org/linux/man-pages/man1/cp.1.html) – the Linux man page with concise option descriptions
<!-- PROSE:outro:end -->

## Related Commands

- [mv](https://www.jpkc.com/db/en/cheatsheets/files-text/mv/) – move or rename files instead of making a copy
- [rm](https://www.jpkc.com/db/en/cheatsheets/files-text/rm/) – delete files and directories
- [ln](https://www.jpkc.com/db/en/cheatsheets/files-text/ln/) – create hard and symbolic links instead of copying

