Copy a directory recursively
Copy a folder and all its contents (subdirectories + files) to a new location.
How to copy a directory recursively in each shell
cp -r src/ dest/`-r` (recursive) is the bare minimum. `cp -a src dest` = `-dR --preserve=all` — preserves perms, ownership, timestamps, symlinks, ACLs. For huge trees + resumable copies: `rsync -a src/ dest/` (note the trailing slash on `src/` — `src/` means "the contents of src", `src` means "src itself"; the same gotcha makes a `dest/src/` copy when you wanted `dest/`).
cp -R src/ dest/Same external `cp`. macOS BSD `cp -R` (uppercase) is the standard form; `cp -r` is a non-standard GNU lowercase alias that ALSO works on macOS. BSD `cp` lacks `-a` — use `cp -pR` for perms + recursive, or install GNU coreutils (`brew install coreutils` → `gcp -a`).
cp -r src/ dest/Same external. Fish globbing: `cp -r src/*.txt dest/` works the same; recursive glob is `**`: `cp -r src/**.txt dest/` (fish-native).
Copy-Item -Path src -Destination dest -Recurse`-Recurse` is mandatory for directories (without it pwsh copies only the empty directory shell, not contents — silent partial copy). `-Force` overwrites existing files at dest without prompting. To preserve ACLs (Windows-specific): `Copy-Item -Recurse` does NOT carry ACLs; use `robocopy src dest /E /COPY:DATSO /R:0` to copy data + ACLs + ownership.
robocopy src dest /E`robocopy` (Robust Copy, Win Vista+) — the only sensible recursive-copy on cmd. `/E` includes EMPTY subdirs (vs `/S` skipping empty ones). `/MIR` makes dest a MIRROR of src (DELETES files in dest not in src — destructive, double-check before running). `/R:N /W:N` retries (default 1M retries with 30s wait — slow on flaky network shares). `xcopy /E /I` is the legacy alternative; `copy` does not recurse at all.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **Trailing-slash semantics — the rsync trap**: `rsync -a src/ dest/` copies the CONTENTS of `src` into `dest`. `rsync -a src dest/` copies `src` ITSELF into `dest` (creating `dest/src/`). Same trap with GNU `cp` — `cp -r src/ dest/` vs `cp -r src dest/` differ by one directory level. Tip: append `/` to BOTH paths to be explicit, or run `ls -d` first to verify the result tree.
- **Preserving timestamps + perms + ACLs**: GNU `cp -a` (= `-dR --preserve=all`) keeps mtime / ctime / mode / owner / group / xattrs / context. BSD `cp -pR` keeps mtime + mode + owner — no xattrs without `-X`. pwsh `Copy-Item -Recurse` keeps perms but NOT NTFS ACLs (separate `Get-Acl` / `Set-Acl` round-trip needed). Robocopy `/COPY:DATSO` (Data + Attributes + Timestamps + Security + Owner) is the most complete on Windows. `rsync -aHAX` adds Hard-links + ACLs + xattrs on Linux.
- **Hard links + sparse files**: GNU `cp -a` preserves HARD-LINK relationships within the source tree (two files hardlinked to the same inode stay hardlinked in dest). BSD `cp` does NOT — each file becomes an independent copy, doubling disk use. `rsync -H` is the explicit hard-link-preservation flag. Sparse files: `cp --sparse=always` (GNU) preserves sparse holes; `rsync --sparse`. Without these, a 1TB sparse-file backup balloons to a real 1TB on dest.
- **Cross-filesystem + network copies**: for copies that may be interrupted (slow disks, flaky network shares, OOM kills), use a RESUMABLE tool. `rsync -a --partial --append-verify src/ dest/` resumes mid-file on next run. `robocopy /Z` (restartable mode) does the same on Windows + retries failed files. Plain `cp -r` / `Copy-Item -Recurse` start over on every retry — wasted bandwidth on every interruption.
Related commands
Related tasks
- Merge multiple files into one— Concatenate the contents of several files into a single output file.
- Split a large file into pieces— Split a single large file into smaller chunks by byte count or line count.
- Find the largest files in a directory— Identify the top N largest files under a directory tree, sorted by size.