Copy Directories Recursively Using cp in Linux
Duplicating directories in the Linux operating system requires the
cp (copy) command to navigate beyond individual data
streams and process nested file trees. This article provides a
straightforward breakdown of how the cp command duplicates
directories using recursive flags, the mechanics of directory traversal,
and the differences between standard recursion and preserving system
metadata.
Why the Recursive Flag Is Required
By default, the cp command is designed to copy single
files. If you run cp source_dir target_dir without any
flags, the operation will fail, displaying an error message such as
cp: -r not specified; omitting directory 'source_dir'.
In Linux, a directory is a special type of file that contains a list
of filenames and their associated inode references. Because a directory
contains other files, symbolic links, and subdirectories, the standard
linear byte-copying mechanism cannot duplicate it. The cp
command requires explicit instructions to descend into that directory
and replicate its internal hierarchy.
How Recursive Copying Works
When you supply a recursive flag, the cp command shifts
from copying a single file to traversing a directory tree:
- Tree Traversal: The command opens the source directory and reads its contents.
- Directory Creation: For every subdirectory
encountered,
cpcreates an equivalent directory in the destination path. - Data Duplication: For every regular file
encountered,
cpcopies the data from source to destination. - Descent: The command recursively applies these steps down through all nested child directories until the entire tree has been mirrored.
Common Recursive Flags
The -r and -R
Flags
In GNU coreutils (standard on most Linux distributions), both
-r and -R denote recursive copying and can be
used interchangeably:
cp -r /path/to/source_dir /path/to/target_dircp -R /path/to/source_dir /path/to/target_dirWhile both replicate directory structures, POSIX standards
traditionally define -R as the standard implementation for
recursive copying. For maximum script portability across non-GNU
environments (such as BSD or older UNIX systems), -R is the
preferred flag.
The -a (Archive) Flag
While -r duplicates the structure and file contents, it
generates new destination files using the default permissions, current
user ownership, and current timestamps. To copy a directory recursively
while preserving original attributes, the archive flag (-a)
is standard practice:
cp -a /path/to/source_dir /path/to/target_dirThe -a flag combines:
-d: Preserves symbolic links rather than copying the files they point to.-R: Recursive copying.--preserve=all: Retains original file modes (permissions), ownership, timestamps, and extended attributes (such as SELinux contexts).
Trailing Slash Behavior
The behavior of cp -r depends on the presence of the
destination directory:
- Destination does not exist:
cp -r dirA dirBcreates a new directory nameddirBcontaining the contents ofdirA. - Destination exists:
cp -r dirA dirBplacesdirAinsidedirB, resulting indirB/dirA. - Copying contents only: If you append a slash and a
wildcard (
cp -r dirA/* dirB/), the command copies only the contents ofdirAdirectly intodirB, omitting the parent container folder.