The cp command in Linux
cp copies files and directories. Its two arguments are read as "from" then "to": cp source destination. If the destination is an existing directory, the copy is placed inside it; otherwise the destination is the name of the new copy. Copying directories requires -r.
How cp works
At its core cp is a read/write loop: open the source, read blocks, write them to a new file. Metadata is not part of that stream — permissions, timestamps and ownership live in the inode — so faithful copies require explicitly asking for them, which is what -p and -a do.
Modern filesystems complicate the story in a useful way. On btrfs, XFS and APFS, cp can request a reflink clone: a new file that shares the same data blocks copy-on-write, making the "copy" instant and nearly free until one side is modified. And sparse files (huge files that are mostly holes, like VM disk images) are detected and preserved with --sparse — naive copying would materialize gigabytes of zeros.
Syntax
cp [OPTIONS] SOURCE... DEST Common options
| Option | What it does |
|---|---|
-r | Recursive: copy directories and their contents. |
-i | Interactive: ask before overwriting an existing file. |
-n | No clobber: never overwrite an existing file. |
-p | Preserve mode, ownership and timestamps. |
-a | Archive: recursive copy preserving everything (equivalent to -rp plus links). The standard choice for backups. |
-v | Verbose: show each file as it is copied. |
How to use cp: examples
$ cp report.txt report-backup.txt Copy a file, giving the copy a new name.
$ cp report.txt documents/ Copy a file into an existing directory, keeping its name.
$ cp -r website website-v2 Copy an entire directory tree.
$ cp -i config.yml config.yml.bak Ask before overwriting if the destination already exists.
$ cp *.jpg ~/pictures/ Copy every JPG in the current directory to another folder.
$ cp -a /var/www /backup/www Archive mode: an exact copy preserving permissions, timestamps and symlinks.
Real-world use cases for cp
Backing up before editing config
The professional reflex before touching any server config: cp nginx.conf nginx.conf.bak. Two seconds of insurance; if the edit breaks something, cp the backup over it and reload. Sysadmin muscle memory, and the reason .bak files litter every server on earth.
Cloning a project as a template
cp -a old-project new-project duplicates a whole tree preserving permissions and symlinks — then strip what shouldn't carry over (rm -rf new-project/.git). Archive mode (-a) is the difference between a faithful copy and one with subtly broken scripts.
Try cp yourself
This is a live sandbox with a small filesystem (documents/, notes.txt,
backup.sh…). Nothing you do here can break anything — experiment freely.
Try: cp notes.txt notes-backup.txt
Pro tips and common mistakes
- cp -a (archive) should be your default for directories: it preserves permissions, timestamps and symlinks, which plain -r does not.
- Quick versioned backup with brace expansion: cp config.yml{,.bak} expands to cp config.yml config.yml.bak.
- cp -u copies only when the source is newer than the destination — a poor man's sync for simple cases (rsync does it properly).
- Copying many files? cp shows nothing by default; add -v to watch progress, or use rsync --info=progress2 for big trees.
Frequently asked questions about cp
How do I copy a directory in Linux?
Add the -r (recursive) flag: cp -r sourcedir destdir. Without it, cp skips directories with an "omitting directory" message.
Does cp overwrite files without asking?
Yes, by default cp silently overwrites existing destination files. Use cp -i to be asked first, or cp -n to never overwrite.
What is the difference between cp -r and cp -a?
Both copy recursively, but -a (archive) also preserves permissions, ownership, timestamps and symbolic links, making it the right choice for backups and migrations.
Related commands
List the contents of a directory, with options for hidden files, long format, sorting and more.
mkdirCreate one or many directories, including whole nested paths with -p.
rmDelete files and directories — and understand -r, -f and why there is no trash bin.
mvMove files between directories and rename them — the same operation in Linux.