The cp command in Linux copies files and directories to a new location. Its basic form is cp SOURCE DEST for single files and cp -r SOURCE_DIR DEST_DIR for directories.
Key options include -i (prompt before overwrite), -n (no overwrite), -a (archive/preserve attributes), and -v (verbose) for safe, transparent copying. Whether you manage a personal Linux setup or production servers, mastering the cp command in Linux is essential.
In this guide, you’ll learn the syntax, safest flags, and real world examples used by system administrators every day, plus expert tips from hosting environments, so you avoid data loss and copy exactly what you intend.
What is the cp Command in Linux?
The cp (copy) command duplicates files or directories from a source to a destination. It’s part of GNU coreutils on most Linux distributions and supports powerful options to preserve permissions, ownership, timestamps, extended attributes, and links crucial for servers, containers, and development workflows.
cp Command Syntax
Here’s the general syntax you’ll use most often:
cp [OPTIONS] SOURCE DEST
cp [OPTIONS] SOURCE... DIRECTORY
cp [OPTIONS] -t DIRECTORY SOURCE...
Important notes:
- If DEST is a directory, cp places copies inside that directory.
- Copying directories requires
-ror-R(recursive). - Use
-a(archive) to preserve attributes and structure, ideal for backups and migrations.
Basic cp Examples (Files)
Copy a file to a new file name:
cp report.txt report-backup.txt
Copy a file into a directory:
cp report.txt /var/www/html/
Copy multiple files into a directory:
cp index.html styles.css app.js /var/www/html/
Copy files to a directory using the target directory option (-t):
cp -t /var/www/html/ index.html styles.css app.js
Copying Directories with cp -r
To copy a directory and its contents recursively, use -r or -R:
cp -r assets/ /var/www/html/
Copy a directory into a new directory name:
cp -r /etc/nginx/ nginx-backup/
On servers, always combine recursion with safety flags (like -i or backups) to avoid accidental overwrites.
Preserving Permissions and Metadata (cp -a, -p, –preserve)
When moving website code, system configs, or user data, preserving attributes matters. The -a flag (archive) is the go-to, equivalent to -dR --preserve=all on GNU/Linux.
# Best practice for backups and migrations
cp -a /var/www/html/ /backups/html-$(date +%F)/
Preserve selected attributes with -p or --preserve:
# Preserve mode, ownership, and timestamps
cp -p app.service /etc/systemd/system/
# Preserve specific attributes (GNU cp)
cp --preserve=mode,ownership,timestamps,links,xattr,context source dest
On shared hosting or containers, ownership might not be preserved unless you run the command with appropriate privileges (e.g., sudo). Verify with ls -l after copying.
Controlling Overwrites Safely (-i, -n, -f, -u)
Overwrites are a common source of data loss. Use these flags to control behavior:
- -i: Interactive; ask before overwrite.
- -n: No clobber; do not overwrite existing files.
- -f: Force overwrite by removing destination first.
- -u: Only copy when SOURCE is newer than DEST or DEST is missing.
# Safer: prompt to overwrite
cp -i config.php /var/www/html/
# Never overwrite existing files
cp -n *.png /var/www/html/images/
# Update only when newer (handy for deployments)
cp -u build/* /var/www/html/
Combine with -v (verbose) to see what’s happening:
cp -uv build/* /var/www/html/
Working with Links: Hard Links, Symlinks, and Dereferencing
Links matter in application directories and shared assets.
Understand how cp treats them:
- -s: Create symbolic links instead of copying files.
- -l: Create hard links instead of copying (same inode, same filesystem only).
- -P: Do not dereference symlinks (copy the link as a link).
- -L: Dereference symlinks (copy the target file contents).
- -H: Follow symlinks listed on the command line only.
# Copy symlinks as symlinks (archive mode includes -d which behaves like -P)
cp -a site/ /var/www/
# Copy the contents that symlinks point to
cp -Lr site/ /var/www/
# Create symlinks instead of copying data
cp -s bigfile.iso bigfile-link.iso
Automatic Backups While Copying (–backup, -b, -S)
Create backups of overwritten files automatically, a lifesaver on production servers:
# Backup overwritten files using default suffix ~
cp -b settings.php /var/www/html/
# Custom suffix for easier rollbacks
cp --backup=numbered -S .bak settings.php /var/www/html/
Backup controls (GNU cp): none, simple, numbered, existing. Use numbered for versioned backups like file.bak.~1~, ~2~, etc.
Advanced and Performance Options (GNU cp)
On modern filesystems, cp offers advanced behaviors:
- –reflink[=auto|always|never]: Copy on write clone on btrfs/XFS, instant and space efficient.
- –sparse=auto|always|never: Efficiently handle sparse files (VM images, databases).
- –attributes only: Copy metadata without file contents.
- –parents: Recreate source path under the destination.
- -T: Treat DEST as a normal file (avoid implicit directory behavior).
# Fast, space-saving clone if supported
cp --reflink=auto vm.qcow2 vm-copy.qcow2
# Preserve path structure under /backup
cp --parents /etc/nginx/nginx.conf /backup/
Some flags vary on non GNU systems (e.g., macOS/BSD). Check man cp for your platform.
Wildcards, Patterns, and Quoting
Shell wildcards expand before cp runs. Use quotes to handle spaces or special characters safely.
# Copy all .log files
cp *.log /var/log/archive/
# Copy files with spaces in the name
cp "My Report Q4.pdf" "/srv/docs/Reports/"
# Copy only today’s build artifacts
cp build-$(date +%F)-*.tar.gz /releases/
cp does not support “exclude” patterns. For selective copies, consider find or rsync.
# Example: copy everything except *.log using rsync semantics
rsync -av --exclude='*.log' src/ dest/
Real World Use Cases on Servers and Hosting
- Backup configs before edits:
cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak - Deploy static sites safely:
cp -anv build/ /var/www/html/(no overwrite existing) - Rollback friendly changes:
cp -bv -S .bak index.php /var/www/html/ - Preserve permissions when migrating webroots:
cp -a /var/www/html/ /mnt/new-disk/html/ - Clone large images fast with reflinks on supported filesystems:
cp --reflink=auto image.qcow2 image-test.qcow2
If you manage VPS, cloud, or dedicated servers with YouStable, we recommend practicing on a staging path and enabling backups. Combine -a, -i, and --backup during critical changes for maximum safety.
cp vs mv vs rsync vs scp: Which Should You Use?
- cp: Local copies; fast, simple, preserves attributes with
-a. No network support and no built in “exclude”. - mv: Move/rename; faster on the same filesystem (metadata update). Not a copy.
- rsync: Incremental, network capable, filters/excludes, progress, and resume. Ideal for deployments and backups.
- scp/sftp: Transfer over SSH. Use for remote copies; prefer
rsync -e sshfor efficiency.
Best Practices and Safety Tips
- Dry run the path: Use
lsorechoto confirm wildcards before copying. - Prefer archive mode for system data:
cp -apreserves what matters. - Prevent clobbering: Start with
-ior-non production systems. - Back up automatically: Add
-b --backup=numbered -S .bakfor critical files. - Quote paths: Protect spaces and special characters with quotes.
- Verify: Use
-vand check withdiffor hashes for high stakes copies. - Permissions: After copying web apps, verify ownership (
chown) and modes (chmod).
Troubleshooting Common cp Errors
- Permission denied: Use
sudoor adjust permissions/SELinux context. - Not a directory: You intended a directory but DEST is a file; use
-Tcarefully to force file behavior. - Omitting directory: Forgot
-rfor directories add it and rerun. - Broken symlinks copied: Use
-Lif you need the target’s contents instead of the link. - Attributes lost: Use
-aor--preserve; ensure filesystem and user privileges allow preservation.
cp Command Quick Reference (Most Used Flags)
- -r/-R: Recursive directory copy
- -a: Archive (preserve all, copy symlinks as symlinks)
- -p: Preserve mode, ownership, timestamps
- -i/-n/-f/-u: Overwrite control (interactive/no clobber/force/update)
- -v: Verbose output
- -b –backup -S: Backup overwritten files with suffix
- -s/-l: Make symlinks or hard links instead of copying
- -L/-P/-H: Dereference or preserve symlinks
- –reflink: Copy on write clone when supported
- –parents: Recreate source path
- -t/-T: Specify target directory / treat DEST as a file
FAQ’s
1. What does cp -a do in Linux?
cp -a is “archive” mode. It copies directories recursively and preserves almost everything permissions, ownership, timestamps, symbolic links, hard links, and extended attributes making it ideal for backups and migrations on servers.
2. How do I copy a directory in Linux?
Use cp -r or cp -R. For example, cp -r project/ /opt/apps/. To preserve permissions and links, prefer cp -a project/ /opt/apps/. Add -v for progress-like output and -i to avoid accidental overwrites.
3. How can I avoid overwriting existing files with cp?
Use -n (no clobber) to skip existing files or -i (interactive) to prompt before overwrite. For extra safety, enable backups with -b or --backup=numbered -S .bak so you can roll back changes quickly.
4. Should I use cp or rsync for deployments?
For simple local copies, cp is fine. For selective updates, excludes, bandwidth efficiency, or remote transfers, rsync is superior. Many admins deploy with rsync -av --delete to keep targets in sync and log changes clearly.
5. Why are file permissions different after copying?
If you used plain cp, default umask and user may alter permissions/ownership. Use cp -a or -p to preserve attributes. Also ensure you have the privileges to set ownership (often requires sudo), and verify with ls -l afterward.
Mastering the cp command in Linux helps you copy safely, preserve what matters, and move faster in real world server environments. If you host on YouStable, our support team can guide you on safe file operations during migrations and deployments.