How to Copy a Directory in Linux: Commands, Options, and What to Know First

Copying a directory in Linux sounds straightforward — and in many cases it is — but the details matter. Whether you're backing up a project folder, migrating files to a new drive, or duplicating a configuration directory, the command you use and the flags you pass will determine whether you get exactly what you expected or end up with missing files, broken permissions, or a partial copy.

The Core Command: cp -r

The standard tool for copying directories in Linux is cp, and the key flag is -r (or --recursive). Without it, cp will refuse to copy a directory and return an error.

Basic syntax:

cp -r source_directory/ destination_directory/ 

For example, to copy a folder called projects into a folder called backup:

cp -r projects/ backup/ 

If backup/ already exists, Linux will place projects/inside it, creating backup/projects/. If backup/ does not exist, Linux will create it and copy the contents of projects/ directly into it. This distinction trips up a lot of people — the trailing slash and whether the destination exists both affect the outcome.

Common Flags That Change the Behavior

The -r flag alone gets the job done for basic use cases, but cp has several options worth knowing:

FlagWhat It Does
-r or -RRecursive — required for directories
-vVerbose — prints each file as it's copied
-pPreserves timestamps, ownership, and permissions
-aArchive mode — combines -r, -p, and more; preserves symlinks
-uOnly copies files that are newer than existing destination files
-nNo-overwrite — skips files that already exist at the destination
--progressShows progress (available in some versions via rsync instead)

-a (archive mode) is especially useful when you need an exact copy — it preserves symbolic links, file permissions, ownership, and timestamps all at once. It's the preferred choice for backups and system-level copies.

cp -a source_directory/ destination_directory/ 

When cp Isn't the Right Tool 🛠️

For large directories, remote copies, or incremental backups, rsync is often a better choice than cp. It offers more granular control and is significantly more efficient when copying to a destination that already has some of the files.

Basic rsync syntax for directories:

rsync -av source_directory/ destination_directory/ 

The -a flag in rsync enables archive mode (similar to cp -a), and -v gives verbose output. One important note: trailing slashes in rsync behave differently than in cp. In rsync, including a trailing slash on the source copies the contents of the directory, not the directory itself. Leaving it off copies the directory as a whole.

Other tools that come up depending on the use case:

  • tar — useful for copying entire directory trees while preserving structure, especially for archiving or transferring between systems
  • scp — for copying directories to or from remote machines over SSH
  • dd — used for low-level disk or partition copies, not typical file/folder operations

Permissions, Ownership, and What Gets Lost

By default, cp -r without -p or -a will not preserve the original file permissions, ownership, or timestamps. The copied files will be owned by the user running the command and will carry the current timestamp.

This matters in different ways depending on your situation:

  • Personal project folders: usually not a concern
  • Web server directories: permissions like 755 or 644 may need to be intact for the application to function correctly
  • System configuration directories: ownership and permissions are often critical
  • Backup workflows: you almost always want -a to preserve everything

If you're copying as a regular user, you also can't preserve ownership of files that belong to other users — you'd need sudo or root access for that.

Hidden Files and Subdirectories

cp -r copies hidden files (files beginning with .) and all subdirectories automatically. This is one area where Linux's recursive copy behavior is predictably thorough — you don't need a separate flag for dotfiles.

However, empty subdirectories are also copied, which may or may not be what you want. If you need to exclude certain files or patterns, rsync gives you --exclude options that cp doesn't offer natively.

How Your Setup Affects the Right Approach 🖥️

The "correct" way to copy a directory in Linux shifts depending on a few variables:

Destination type: Copying to a local drive is different from copying to a network mount, an external USB drive (which may use FAT32 and not support Linux permissions), or a remote server over SSH.

Directory size: A few hundred files copies quickly with cp. Millions of files, or terabytes of data, benefit from rsync's efficiency and ability to resume interrupted transfers.

Frequency: A one-time copy is different from a recurring backup. Incremental tools like rsync make more sense when you're running the operation repeatedly.

Linux distribution and version: Most distributions include GNU cp, but behavior details — including available flags — can vary slightly between versions and between GNU and BSD implementations (relevant if you're working across Linux and macOS).

User privileges: System-level copies involving protected directories will require elevated permissions, which changes how you invoke the command and what side effects to watch for.

What works cleanly for one setup — copying a personal project folder on Ubuntu — may need a different approach entirely when you're maintaining file integrity across a production server migration. The command syntax is simple; knowing which version of it fits your specific directory, destination, and requirements is the part that depends entirely on what you're working with. 🗂️