Where to start First steps track · 15 stages
Linux Labs

cp — copy files and directories

5 min Ubuntu 24.04 · GNU coreutils 9.4

The cp command copies files and directories, with overwrite prompts, preserved permissions and times, recursively.

Cheat sheet

10 commands Printable version
  • cp app.conf app.conf.bak a copy next to it, another name
  • cp app.conf /tmp/ into a directory, same name
  • cp a.txt b.txt docs/ several files into a directory
  • cp -r project project-copy a whole directory
  • cp -a /etc/nginx ~/nginx-backup keep permissions, owner, times
  • cp -i app.conf /etc/app.conf ask before overwriting
  • cp -n app.conf /etc/app.conf never overwrite an existing file
  • cp -u *.conf /srv/conf/ only if the source is newer
  • cp -v a.txt b.txt print what gets copied
  • cp -r project/. backup/ a directory's contents, not itself

Overview

cp source destination makes a copy. If the destination is an existing directory, the copy goes inside it under the same name. If the destination doesn't exist, a new file with that name appears.

text
student@ubuntu:~$ cp -v app.conf app.conf.bak
'app.conf' -> 'app.conf.bak'

With no options cp copies files only and skips directories. Directories are copied with -r (recursive) or -a (archive — also permissions, owner, times, and symlinks as symlinks).

cp silently overwrites an existing destination file. When a mistake is expensive, add -i or -n.

Options

10

cp and mv share many options: -i, -n, -u, -v, -b, -t. Full list — man cp.

Option What it does Example
-r Copy directories recursively, with everything inside (same as -R). cp -r project project-copy
-a Archive mode — recursive, keeping permissions, owner, times and links. cp -a /etc/nginx ~/nginx-backup
-i Prompt before overwriting an existing file. cp -i app.conf /etc/app.conf
-n Never overwrite existing files. cp -n app.conf /etc/app.conf
-u Copy only when the source is newer than the destination or it's missing. cp -u *.conf /srv/conf/
-v Print each copy — 'a' -> 'b'. cp -v a.txt b.txt
-p Preserve mode, ownership and timestamps. cp -p app.conf app.conf.bak
-b Before overwriting, keep the old file with ~ appended to its name. cp -b new.conf app.conf
-t dir Destination directory as the first argument — handy with find and xargs. cp -t /srv/www/ index.html style.css
--parents Recreate the source path inside the destination directory. cp --parents etc/app.conf /backup/

Nothing found. Try a shorter query.

Recipes

5

Back up a config before editing

bash
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config
diff /etc/ssh/sshd_config.bak /etc/ssh/sshd_config   # what changed

-a keeps the owner and permissions, so the backup can be put back as is.

A directory into an existing directory, and "into" it

bash
cp -r src dst        # dst exists → dst/src; else dst is the copy
cp -r src/. dst/     # the contents of src straight into dst

The same command gives different results depending on whether dst exists. Check the result: ls dst.

Copy many files into one directory

bash
cp -t /srv/www/ index.html style.css app.js   # destination first
find . -name '*.conf' -exec cp -t /tmp/conf/ {} +   # what find found

Keep the previous version

bash
cp -b new.conf app.conf      # the old app.conf becomes app.conf~

Between machines

cp works within one machine. Over the network use rsync or scp (see ssh-client).

Troubleshooting

6

cp: -r not specified; omitting directory

The source is a directory and -r is missing. Add -r or -a: cp -a src dst.

cp: cannot stat 'x': No such file or directory

There's no source at that path. Check pwd and the name with ls; complete the path with Tab.

cp: cannot create regular file: Permission denied

You can't write to the destination directory. Check ls -ld dir; system directories need sudo cp.

The copy is owned by root, not the user

sudo cp creates new files as root. Keep the source's owner with -a, or fix the owner: sudo chown student:student file — see chmod-chown.

The copy has different permissions or times

Without -p or -a the copy gets the current time and permissions from the umask. For backups use cp -a.

No space left on device

The destination filesystem is full. df -h path shows the free space — see disk-usage.

Danger zone

2

Silent overwrite

cp new.conf /etc/app.conf replaces a working config without asking, and the old text is gone. Make a backup first (cp -a … .bak), then replace — or use cp -i.

cp -r into an existing directory

If the destination directory already exists, cp -r src dst puts the copy inside it — dst/src. A script that expects "dst becomes the copy" will start nesting directories when run a second time.

See also

  • mv — move or rename instead of copying.
  • rm — delete a copy you don't need.
  • ls — check the result.
  • rsync — copying large trees and over the network.
  • chmod-chown — fix the copy's permissions and owner.
  • files-basics — an overview of the basic file commands.
Loading…