Skip to content

The Linux Command Tutorial series provides rigorous, upstream-verified references for essential system commands across Linux distributions and UNIX-like environments. Each article focuses on a single executable, combining exhaustive option documentation, verified real-world examples, security boundaries, and best practices directly derived from official source documentation and POSIX standards.


1. Introduction

Upstream: GNU Coreutils 9.11 | POSIX: POSIX.1-2024 (with GNU extensions) | Safety Tier: unprivileged-filesystem-write | Scope: File replication, directory tree recursion & CoW reflink cloning

cp copies files and directories. It creates independent replicas of filesystem objects, copying data blocks, reconstructing directory hierarchies, preserving extended attributes, or orchestrating Copy-on-Write (CoW) reflinks on supported filesystems.

  • Upstream Project & Provenance: Distributed in GNU Coreutils (coreutils).
  • Portability & Standards Baseline: Standardized in IEEE Std 1003.1-2024 (POSIX.1-2024). GNU cp extends POSIX with features like --reflink, --backup, --sparse, --update, and --preserve=all.
  • Target Research Implementation: Audited against GNU Coreutils 9.11 (cp(1)).
  • Applicability & Lifecycle: The foundational utility for duplicating files and directory trees.

2. Syntax and Command Model

2.1 Canonical Synopsis

bash
# Copy source to destination file:
cp [OPTION]... [-T] SOURCE DEST

# Copy multiple sources into target directory:
cp [OPTION]... SOURCE... DIRECTORY
cp [OPTION]... -t DIRECTORY SOURCE...

2.2 Execution Model

  • If the destination file does not exist, cp creates it with permissions derived from the source modified by umask (unless -p or -a is given).
  • If the destination file exists, cp opens and overwrites it in place without altering its existing inode or ownership (unless -f removes it first).
  • Target Directory Protection (-T): -T treats DEST strictly as a normal file, preventing accidental nested copies if DEST happens to be a directory.

3. Options

3.1 Primary Operational Flags

Short FlagLong FlagDescriptionPOSIX Defined
-a--archiveSame as -dR --preserve=all (preserves all attributes and links).No
-r, -R--recursiveCopy directories recursively.Yes
-p--preserve[=ATTR]Preserve mode, ownership, and timestamps.Yes
-f--forceIf destination cannot be opened, remove it and try again.Yes
-i--interactivePrompt before overwrite.Yes
-u--update[=WHEN]Copy only when source is newer than destination or missing.No
-l--linkHard link files instead of copying data blocks.No
-s--symbolic-linkMake symbolic links instead of copying.No
N/A--reflink[=WHEN]Control Copy-on-Write (CoW) reflink clones (always, auto, never).No
N/A--sparse=WHENControl sparse file creation (always, auto, never).No
N/A--backup[=CONTROL]Make a backup of each existing destination file.No

4. Basic Usage

4.1 Quick Reference & Common Invocations

Task / ScenarioCommandKey Flags / Behavior
Copy single filecp config.conf config.conf.bakDuplicates file contents
Copy directory (full archive)cp -a /src/dir /dst/dir-a preserves all modes, ownership, timestamps
Copy multiple files to directorycp file1.txt file2.txt /backup/Copies list of files into target folder
Prompt before overwritecp -i src.txt dst.txt-i asks before replacing existing destination
Update only newer filescp -u -r ./src /var/www/-u skips files that are up to date
Fast Copy-on-Write reflinkcp --reflink=auto db.raw snapshot.rawCoW clone on Btrfs/XFS without disk duplication
Create automatic numbered backupcp --backup=numbered file.txt /dst/Creates file.txt.~1~ if file already exists
Sparse VM disk copycp --sparse=always disk.raw disk.bakDetects zero blocks and writes sparse holes

4.2 Simple File Copy

bash
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

4.3 Copying Multiple Files into a Directory

bash
cp file1.txt file2.txt /var/backup/

5. Practical Operations

5.1 Full Archive Copy (Preserving Everything)

Copying a system directory tree while strictly maintaining permissions, timestamps, extended attributes, and symlink structures:

bash
cp -a /opt/app_v1 /opt/app_v2
  • Technical Analysis: -a expands to --preserve=all -d -R. It avoids following symlinks, retains original owner/group IDs (when run as root), and preserves SELinux security contexts.

On modern filesystems (Btrfs, XFS with reflink support, ZFS):

bash
cp --reflink=always database.raw database_snapshot.raw
  • Technical Analysis: Rather than copying gigabytes of storage blocks, --reflink instructs the kernel to allocate a new inode sharing identical extents. The copy completes in milliseconds and consumes 0 additional disk space until modified.

5.3 Safe In-Place Backups Before Overwrites

Creating numbered backups when copying configuration updates:

bash
cp --backup=numbered -v new_config.yaml /etc/service/config.yaml

Sample terminal output:

console
'new_config.yaml' -> '/etc/service/config.yaml' (backup: '/etc/service/config.yaml.~1~')

5.4 Updating Only Stale or Missing Files

bash
cp -u -r ./assets /var/www/html/
  • Skips any destination file whose modification timestamp is equal to or newer than the source.

6. Advanced Usage

6.1 Avoiding Directory Overwriting Traps with -T

When automating deployments via scripts, passing -T guarantees that the source directory replaces or updates the destination directly rather than nesting inside it:

bash
cp -a -T ./src /var/www/current

6.2 Efficient Sparse File Replication

Virtual machine disk images and database files often contain large contiguous blocks of zeros. Copying them with --sparse=always:

bash
cp --sparse=always vm_disk.raw /storage/vm_backup.raw
  • Detects zero-filled blocks and writes filesystem holes instead of physical zeros, saving storage space and I/O bandwidth.

7. Exit Status, Environment, and Configuration

7.1 Exit Status Codes

Exit CodeMeaning
0Success: all files copied successfully.
>0An error occurred (source file unreadable, target permission denied, out of disk space).

8. Safety, Security, and Portability

8.1 Inode Overwrite Behavior

WARNING

Existing Inode Truncation: When cp copies over an existing destination file, it opens and truncates the file in place. Existing hard links pointing to that destination are simultaneously modified, and file ownership remains unchanged.

To guarantee a fresh inode with clean permissions and avoid modifying hard-linked files, pass --remove-destination before writing.

NOTE

  • -P (--no-dereference): Never follow symlinks (default with -d and -a).
  • -L (--dereference): Always follow symlinks and copy target files.
  • -H: Follow symlinks only when explicitly listed on the command line.

9. Best Practices

  1. Use cp -a for Administrative Backups:

    IMPORTANT

    Guidance: Never use cp -r for system backups; use cp -a. Authoritative Justification: GNU documentation notes that cp -r does not preserve ownership, mode bits, or symlinks, resulting in corrupted permissions and broken links.

  2. Leverage --reflink=auto on Modern Linux Storage:

    TIP

    Guidance: Default large data copies to cp --reflink=auto. Authoritative Justification: Enables instant zero-cost cloning on XFS/Btrfs while safely falling back to standard block copies on ext4.

  3. Use -T in Automation Scripts:

    TIP

    Guidance: Always specify -T when copying into a destination that must not nest directories. Authoritative Justification: Prevents non-deterministic directory nesting if destination paths exist.

  4. Use --sparse=auto for Virtual Machine Images:

    TIP

    Guidance: Retain sparse hole allocations during VM image cloning. Authoritative Justification: Prevents unallocated disk blocks from expanding into actual storage consumption.


References

  1. GNU Coreutils cp Manual: https://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html
  2. POSIX.1-2024 cp Specification: The Open Group Base Specifications Issue 8. https://pubs.opengroup.org/onlinepubs/9799919799/utilities/cp.html
  3. Coreutils 9.11 Release Notes: https://git.savannah.gnu.org/cgit/coreutils.git/tree/NEWS

Last updated:

Released under the MIT License.