Skip to content

cp Command Cheat Sheet

cp (copy) is one of the most fundamental Linux commands. Beyond simple file duplication, it supports advanced features like preserving metadata, recursive directory copying, creating backups, and handling sparse files.


Synopsis

cp [OPTION]... [-T] SOURCE DEST
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...

Basic Usage

Copy Single File

cp file.txt copy_of_file.txt

Copy to Directory

cp file1.txt file2.txt /home/user/documents/

Recursive Copy (Directories)

To copy a directory and all its contents, use -r (recursive) or -a (archive).

cp -r src_dir/ dest_dir/

Preserving Attributes (-a)

The -a (archive) flag is effectively -dR --preserve=all. It is the best way to duplicate a directory exactly as is, preserving: - Symbolic links - Permissions - Ownership - Timestamps - Context (SELinux)

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

Backup Options

cp can automatically create backups of destination files before overwriting them.

Simple Backup

Appends a tilde ~ to the existing file.

cp --backup file.txt existing_file.txt
# Result: existing_file.txt (new content), existing_file.txt~ (old content)

Numbered Backup

Creates versioned backups like file.txt.~1~.

cp --backup=numbered new_config.conf /etc/app/config.conf
# Result: config.conf.~1~, config.conf.~2~, etc.

Advanced Copying

Interactive Mode (-i)

Prompts before overwriting. Good for aliases (alias cp='cp -i').

cp -i file.txt dest/

Update Only (-u)

Copies source only if it is newer than destination or if destination is missing.

cp -u source.txt dest.txt

No Clobber (-n)

Never overwrite existing files.

cp -n source.txt dest.txt

Hard Link (-l): Creates a hard link instead of copying data (saves space, same inode).

cp -l large_file.iso link_to_file.iso

Symbolic Link (-s): Creates a symbolic link.

cp -s /absolute/path/to/source.txt link_name.txt
# Note: Use absolute paths for source when using -s to avoid broken links

Handling Special File Types

Sparse Files (--sparse)

Sparse files use less disk space than their apparent size (e.g., virtual machine disks). By default, cp detects them (--sparse=auto).

To force sparse creation (saving space):

cp --sparse=always disk.img copy.img

On CoW (Copy-on-Write) filesystems like Btrfs or XFS, --reflink creates a lightweight copy. The data blocks are shared until modified, taking up zero extra space initially.

cp --reflink=always heavy_dataset.csv backup_dataset.csv

When copying a symlink, what do you want to copy? The link itself or the file it points to?

  • Default: Follows symlinks in source (copies the file content).
  • -P / --no-dereference: Copies the symbolic link itself (standard with -a).
  • -L / --dereference: Always follow symbolic links.
# Copy the link 'current' as a file 'release-v1.txt'
cp -L current release-backup.txt

# Copy the link structure itself
cp -P link structure/

Visualizing Progress

Standard cp doesn't show a progress bar.

Verbose (-v)

Prints each file name as it is copied.

cp -v -r source/ dest/

Using generic progress tools

If copying huge files, use pv or rsync --progress instead. Or checking status of cp (advanced): Process substitution isn't easy here, but watch can monitor size.


Practical Examples

Quick File Backup

cp file.conf{,.bak}
# Expands to: cp file.conf file.conf.bak

Flatten a Directory Structure

Copy all .jpg files from nested directories into one folder.

find . -name "*.jpg" -exec cp {} /target/folder/ \;

Copy Only Attributes

Don't copy data, just replicate permissions/ownership.

cp --attributes-only source.txt existing_dest.txt

Creating a Template Directory

cp -rT /etc/skel /home/newuser
-T treats destination as a file (prevents creating newuser/skel if newuser exists).


Exit Status

Code Meaning
0 Success
1 Error (often permission denied or file not found)