cp
Copy files and directories
By CMD Script Team · 4 min read · Last updated
cp [OPTIONS] SOURCE... DESTOptions
| Flag | Description |
|---|---|
-r | Recursively copy directories and their contents |
-p | Preserve mode, ownership, and timestamps of the original files |
-i | Prompt before overwriting an existing destination file |
-v | Print a message for each file copied |
-u | Copy only when the source is newer than the destination or the destination is missing |
-a | Archive mode: equivalent to -dR --preserve=all, ideal for full directory backups |
-n | Never overwrite an existing destination file |
Distribution compatibility
- Ubuntu
- Debian
- Fedora
- Arch
- macOS
What it does
cp copies files and, with -r (or -a), entire directory trees, creating independent
duplicates at the destination. Unlike a hard or symbolic link, a copy is a fully
separate set of data — changes to the original afterward do not affect the copy, and
vice versa.
Beginner examples
cp file.txt backup.txt— copy a file to a new name in the same directorycp file.txt /tmp/— copy a file into another directory, keeping its namecp -r project/ project_backup/— recursively copy an entire directorycp -i file.txt existing.txt— prompt before overwriting if the destination existscp -v *.txt /tmp/— copy matching files while printing each one copied
cp -r project/ project_backup/
Advanced examples
- Preserve full attributes for a proper backup:
cp -a project/ project_backup/copies permissions, ownership, timestamps, and symlinks intact, not just the raw content. - Sync a destination without re-copying unchanged files:
cp -u *.log /var/backups/copies only files that are newer than what's already at the destination (a lightweight alternative torsyncfor simple cases). - Copy a directory's contents without copying the top-level directory itself:
cp -r source/. destination/(note the trailing/.) merges contents into an existing destination directory. - Prevent accidental overwrites when scripting bulk copies:
cp -n *.conf /etc/app/conf.d/skips any file that already exists at the destination instead of clobbering it.
cp -au source/ destination/
Common mistakes
- Assuming
cppreserves permissions, ownership, and timestamps by default — it doesn't; the copy gets fresh timestamps and umask-based permissions unless you pass-por-a. - Copying a directory without
-rand getting an "omitting directory" error, then reaching for-rwithout considering whether attributes also need preserving via-a. - Not realizing
cpsilently overwrites an existing destination file by default — no warning, no prompt, unless-ior-nis used. - Confusing
cp source/ dest/(copiessourceas a subdirectory ofdestifdestalready exists) withcp source/. dest/(merges the contents ofsourceintodest) — these produce very different results.
Tips
- Use
cp -awhenever you want a true, attribute-preserving duplicate of a directory tree (backups, migrations) rather than assembling-r -pmanually. - Add
-ito interactivecpcommands where overwriting the wrong file would be costly, especially when using wildcards. - For very large copies, network transfers, or anything that might be interrupted,
prefer
rsyncovercp— it can resume and copy only the differences.
Best practices
- Default to
cp -afor backups and directory duplication so permissions, ownership, and timestamps travel with the data, not just the raw bytes. - Use
-n(never overwrite) in scripts that copy into a shared or pre-populated destination directory, to avoid silently clobbering files that already exist there. - Verify destination paths carefully before running
cp -r— a trailing slash on the source (or its absence) changes whether the directory itself or just its contents get copied into the destination.
Try it yourself
A simulated shell with a sample home directory — experiment freely, nothing leaves your browser. Type help to list supported commands.
Real-world use cases
- Creating a quick backup of a config file before editing it:
cp config.yaml config.yaml.bak. - Duplicating a project directory as a starting point for a new feature branch's local
experiment:
cp -r project/ project-experiment/. - Copying build artifacts into a deployment directory as part of a release script,
using
-vto log exactly what was copied.
Common interview questions
- What's the difference between
cp -randcp -a?-rrecursively copies directory contents but may not preserve attributes;-a(archive mode) recurses and explicitly preserves permissions, ownership, timestamps, and symlinks — better suited for true backups. - Does
cppreserve file permissions by default? No — a plaincpapplies the current process's umask to the new file rather than copying the source's original permissions; use-por-ato preserve them. - What happens if the destination file already exists when you run
cp? By defaultcpsilently overwrites it with no warning;-iprompts for confirmation first, and-nskips the copy entirely rather than overwriting.
Frequently Asked Questions
What's the difference between cp -r and cp -a?
cp -r recursively copies directory contents but, without -p, may not preserve permissions, ownership, or timestamps (behavior varies by implementation). cp -a (archive) is a shorthand that recurses and explicitly preserves all attributes — permissions, ownership, timestamps, and symlinks — making it the safer choice for full backups.
Why did cp overwrite a file I didn't mean to replace?
By default, cp silently overwrites an existing destination file with no warning. Use -i to be prompted first, or -n to never overwrite, if you want a safety net.
Does cp preserve permissions and timestamps by default?
No, not by default — a plain cp creates the new file with the current umask-based permissions and a fresh timestamp. Use -p (or -a) explicitly if you need the original attributes preserved.
Why does rsync get suggested over cp for large copies?
rsync can resume interrupted transfers, copy only changed portions of files, and works efficiently over networks, whereas cp always copies the full file from scratch and has no built-in resume capability.
Cheat sheet
Download a quick-reference cheat sheet for cp.