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:

  1. Tree Traversal: The command opens the source directory and reads its contents.
  2. Directory Creation: For every subdirectory encountered, cp creates an equivalent directory in the destination path.
  3. Data Duplication: For every regular file encountered, cp copies the data from source to destination.
  4. 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_dir
cp -R /path/to/source_dir /path/to/target_dir

While 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_dir

The -a flag combines:

Trailing Slash Behavior

The behavior of cp -r depends on the presence of the destination directory: