Linux cp Command
last modified October 23, 2026
The cp (copy) command in Linux copies files and directories.
It can copy a single file to a new name, several files into a directory, or
whole directory trees, and it offers options to preserve attributes, avoid
overwriting, make backups, and handle symbolic links.
The syntax is cp [options] source target or
cp [options] source... directory. The examples use GNU
cp from coreutils.
Copying a file
The basic form copies a file to a new name.
cp report.txt report-copy.txt
The copy gets the current time as its modification time and is owned by the
user who runs cp. If the target exists, it is overwritten
without warning.
$ cp report.txt report-copy.txt $ ls -l report.txt report-copy.txt -rw-r--r-- 1 jano jano 11 Oct 23 12:52 report-copy.txt -rw-r--r-- 1 jano jano 11 Jan 15 2026 report.txt
Copying into a directory
When the target is a directory, the files are copied into it under their original names.
cp report.txt backup/ cp a.txt b.txt backup/
With multiple sources, the last argument must be a directory. Wildcards
such as cp *.txt backup/ work as well.
$ cp report.txt backup/ $ cp a.txt b.txt backup/ $ ls backup a.txt b.txt report.txt
Copying directories
Directories are copied with the -r (recursive) option.
cp project archive cp -r project archive cp -r project archive
Without -r, cp skips the directory. The first
recursive copy creates archive as a copy of
project. Running the same command again behaves differently:
since archive now exists, project is copied inside
it. To copy the contents of a directory into an existing one, use
cp -r project/. archive/.
$ cp project archive
cp: -r not specified; omitting directory 'project'
$ cp -r project archive
$ tree archive
archive
├── docs
│ └── README.md
└── src
└── app.py
3 directories, 2 files
$ cp -r project archive
$ tree -d archive
archive
├── docs
├── project
│ ├── docs
│ └── src
└── src
6 directories
Avoiding overwrites
The -i option asks before overwriting, and -n
never overwrites existing files.
cp -i draft.txt report.txt cp -n draft.txt report.txt
We answer n to the prompt, and -n skips the
existing file silently, so report.txt keeps its content. Many
users define alias cp='cp -i' for interactive shells.
$ echo "draft" > draft.txt $ cp -i draft.txt report.txt cp: overwrite 'report.txt'? n $ cp -n draft.txt report.txt $ cat report.txt Q3 results
Verbose output
The -v option prints each copied file.
cp -v a.txt b.txt backup/ cp -rv project/docs docs-copy
Verbose output shows the source and destination of every file, which helps to follow recursive copies.
$ cp -v a.txt b.txt backup/ 'a.txt' -> 'backup/a.txt' 'b.txt' -> 'backup/b.txt' $ cp -rv project/docs docs-copy 'project/docs' -> 'docs-copy' 'project/docs/README.md' -> 'docs-copy/README.md'
Preserving attributes
The -p option preserves the mode, ownership, and timestamps of
the files. The -a (archive) option preserves everything and
copies directories recursively.
sudo cp key.pem /tmp/plain.pem sudo cp -p key.pem /tmp/kept.pem cp -a key.pem latest.txt keep/
The plain copy made by root belongs to root and has a new timestamp, while
the -p copy keeps the original owner and date. Preserving
ownership requires root. The -a option, equivalent to
-dR --preserve=all, also copies symbolic links as links, which
makes it the right choice for backups.
$ ls -l key.pem -rw------- 1 jano jano 7 Jan 15 2026 key.pem $ sudo cp key.pem /tmp/plain.pem $ sudo cp -p key.pem /tmp/kept.pem $ ls -l /tmp/plain.pem /tmp/kept.pem -rw------- 1 jano jano 7 Jan 15 2026 /tmp/kept.pem -rw------- 1 root root 7 Oct 23 12:53 /tmp/plain.pem $ mkdir keep $ cp -a key.pem latest.txt keep/ $ ls -l keep total 4 -rw------- 1 jano jano 7 Jan 15 2026 key.pem lrwxrwxrwx 1 jano jano 10 Oct 23 12:52 latest.txt -> report.txt
Copying only newer files
The -u option copies a file only when the destination is
missing or older than the source.
cp -uv a.txt b.txt backup/
We modified a.txt, so it is copied; b.txt is
unchanged and skipped. For synchronizing larger trees,
rsync is a better tool.
$ echo "new" > a.txt $ cp -uv a.txt b.txt backup/ 'a.txt' -> 'backup/a.txt'
Making backups
The --backup option keeps the existing destination file under
a backup name before overwriting it.
cp --backup=numbered b.txt backup/a.txt
Each run renames the previous a.txt to a numbered backup.
-b makes simple backups with a tilde suffix.
$ cp --backup=numbered b.txt backup/a.txt $ cp --backup=numbered b.txt backup/a.txt $ ls backup a.txt a.txt.~1~ a.txt.~2~ b.txt report.txt
Symbolic links
By default, cp follows a symbolic link given on the command line
and copies the file it points to. The -P option copies the link
itself.
cp latest.txt copy1.txt cp -P latest.txt copy2.txt
copy1.txt is a regular file with the content of
report.txt, while copy2.txt is another link. In
recursive mode with -r, GNU cp copies links as
links; -L forces following them.
$ cp latest.txt copy1.txt $ cp -P latest.txt copy2.txt $ ls -l copy1.txt copy2.txt -rw-r--r-- 1 jano jano 11 Oct 23 12:53 copy1.txt lrwxrwxrwx 1 jano jano 10 Oct 23 12:53 copy2.txt -> report.txt
Creating links instead of copies
The -l and -s options create hard or symbolic links
instead of copying data.
cp -l report.txt report-hard.txt cp -s report.txt report-sym.txt
The hard link shares the inode number with the original, and the link count
rose to 2. cp -al creates a tree of hard links, a cheap snapshot
technique. See the ln command for more on
links.
$ cp -l report.txt report-hard.txt $ cp -s report.txt report-sym.txt $ ls -li report.txt report-hard.txt report-sym.txt 2628330 -rw-r--r-- 2 jano jano 11 Jan 15 2026 report-hard.txt 2628430 lrwxrwxrwx 1 jano jano 10 Oct 23 12:53 report-sym.txt -> report.txt 2628330 -rw-r--r-- 2 jano jano 11 Jan 15 2026 report.txt
Keeping the directory structure
The --parents option recreates the source path under the
target directory.
cp --parents project/src/app.py project/docs/README.md backup/
Instead of placing both files directly into backup,
cp creates the intermediate directories. This is handy for
copying selected files while keeping their layout.
$ cp --parents project/src/app.py project/docs/README.md backup/
$ tree backup/project
backup/project
├── docs
│ └── README.md
└── src
└── app.py
3 directories, 2 files
Common errors
cp reports missing sources, directories without
-r, and permission problems.
cp missing.txt backup/ cp project backup/ cp report.txt /etc/
Writing into /etc requires root privileges. Copying requires read
permission on the source and write permission on the target directory.
$ cp missing.txt backup/ cp: cannot stat 'missing.txt': No such file or directory $ cp project backup/ cp: -r not specified; omitting directory 'project' $ cp report.txt /etc/ cp: cannot create regular file '/etc/report.txt': Permission denied
Best practices for cp
- Use -a for backups: It preserves attributes and links.
- Protect existing files: Use
-i,-n, or--backup. - Mind existing targets: Copying a directory to an existing directory nests it.
- Quote names: Use
cp -- "$src" "$dst"in scripts. - Use rsync for large trees: It copies only changes and can resume.
Source
In this article, we have used the cp command to copy files and
directories, avoid overwrites, preserve attributes, make backups, handle
symbolic links, and keep directory structures.
Author
List all Linux tutorials.