| title | Linux Command Tutorial: cp | ||||
|---|---|---|---|---|---|
| date | 2026-09-12 00:00:00 +0000 | ||||
| categories |
|
||||
| tags |
|
||||
| draft | false | ||||
| slug | linux-cp-tutorial | ||||
| description | Authoritative reference tutorial for cp (GNU Coreutils), detailing copy algorithms, reflink COW copies, sparse files, attribute preservation, and POSIX portability. | ||||
| upstream_suite | gnu-coreutils | ||||
| upstream_version | GNU Coreutils 9.11 | ||||
| posix_standard | POSIX.1-2024 | ||||
| research_date | 2026-09-12 |
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.
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
cpextends 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.
# 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...- If the destination file does not exist,
cpcreates it with permissions derived from the source modified byumask(unless-por-ais given). - If the destination file exists,
cpopens and overwrites it in place without altering its existing inode or ownership (unless-fremoves it first). - Target Directory Protection (
-T):-TtreatsDESTstrictly as a normal file, preventing accidental nested copies ifDESThappens to be a directory.
| Short Flag | Long Flag | Description | POSIX Defined |
|---|---|---|---|
-a |
--archive |
Same as -dR --preserve=all (preserves all attributes and links). |
No |
-r, -R |
--recursive |
Copy directories recursively. | Yes |
-p |
--preserve[=ATTR] |
Preserve mode, ownership, and timestamps. | Yes |
-f |
--force |
If destination cannot be opened, remove it and try again. | Yes |
-i |
--interactive |
Prompt before overwrite. | Yes |
-u |
--update[=WHEN] |
Copy only when source is newer than destination or missing. | No |
-l |
--link |
Hard link files instead of copying data blocks. | No |
-s |
--symbolic-link |
Make symbolic links instead of copying. | No |
| N/A | --reflink[=WHEN] |
Control Copy-on-Write (CoW) reflink clones (always, auto, never). |
No |
| N/A | --sparse=WHEN |
Control sparse file creation (always, auto, never). |
No |
| N/A | --backup[=CONTROL] |
Make a backup of each existing destination file. | No |
| Task / Scenario | Command | Key Flags / Behavior |
|---|---|---|
| Copy single file | cp config.conf config.conf.bak |
Duplicates file contents |
| Copy directory (full archive) | cp -a /src/dir /dst/dir |
-a preserves all modes, ownership, timestamps |
| Copy multiple files to directory | cp file1.txt file2.txt /backup/ |
Copies list of files into target folder |
| Prompt before overwrite | cp -i src.txt dst.txt |
-i asks before replacing existing destination |
| Update only newer files | cp -u -r ./src /var/www/ |
-u skips files that are up to date |
| Fast Copy-on-Write reflink | cp --reflink=auto db.raw snapshot.raw |
CoW clone on Btrfs/XFS without disk duplication |
| Create automatic numbered backup | cp --backup=numbered file.txt /dst/ |
Creates file.txt.~1~ if file already exists |
| Sparse VM disk copy | cp --sparse=always disk.raw disk.bak |
Detects zero blocks and writes sparse holes |
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bakcp file1.txt file2.txt /var/backup/Copying a system directory tree while strictly maintaining permissions, timestamps, extended attributes, and symlink structures:
cp -a /opt/app_v1 /opt/app_v2- Technical Analysis:
-aexpands 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):
cp --reflink=always database.raw database_snapshot.raw- Technical Analysis: Rather than copying gigabytes of storage blocks,
--reflinkinstructs the kernel to allocate a new inode sharing identical extents. The copy completes in milliseconds and consumes 0 additional disk space until modified.
Creating numbered backups when copying configuration updates:
cp --backup=numbered -v new_config.yaml /etc/service/config.yamlSample terminal output:
'new_config.yaml' -> '/etc/service/config.yaml' (backup: '/etc/service/config.yaml.~1~')cp -u -r ./assets /var/www/html/- Skips any destination file whose modification timestamp is equal to or newer than the source.
When automating deployments via scripts, passing -T guarantees that the source directory replaces or updates the destination directly rather than nesting inside it:
cp -a -T ./src /var/www/currentVirtual machine disk images and database files often contain large contiguous blocks of zeros. Copying them with --sparse=always:
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.
| Exit Code | Meaning |
|---|---|
0 |
Success: all files copied successfully. |
>0 |
An error occurred (source file unreadable, target permission denied, out of disk space). |
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-dand-a).-L(--dereference): Always follow symlinks and copy target files.-H: Follow symlinks only when explicitly listed on the command line.
-
Use
cp -afor Administrative Backups:[!IMPORTANT] Guidance: Never use
cp -rfor system backups; usecp -a. Authoritative Justification: GNU documentation notes thatcp -rdoes not preserve ownership, mode bits, or symlinks, resulting in corrupted permissions and broken links. -
Leverage
--reflink=autoon 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. -
Use
-Tin Automation Scripts:[!TIP] Guidance: Always specify
-Twhen copying into a destination that must not nest directories. Authoritative Justification: Prevents non-deterministic directory nesting if destination paths exist. -
Use
--sparse=autofor 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.
- GNU Coreutils cp Manual: https://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html
- POSIX.1-2024 cp Specification: The Open Group Base Specifications Issue 8. https://pubs.opengroup.org/onlinepubs/9799919799/utilities/cp.html
- Coreutils 9.11 Release Notes: https://git.savannah.gnu.org/cgit/coreutils.git/tree/NEWS