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
Create Links Instead of Copying
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
Reflinks (--reflink)
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
Managing Symbolic Links
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) |