/flags/coreutils/cp-a-archive
cp -a: copy a directory and preserve timestamps, permissions and links
- tool
- GNU coreutils
- command
- cp
- flag
- -a, --archive
- default
- off (copies get new timestamps; directories need -r)
cp -a SOURCE DEST copies files and whole directory trees while keeping their metadata: modification times, permission bits, ownership (when you are root), symbolic links as links, hard links between copied files, and extended attributes. In GNU cp it is shorthand for -dR --preserve=all. Use it for backups, moving a data directory to a new disk, or any copy that must look identical to the original. A plain cp refuses directories (see cp: -r not specified; omitting directory) and stamps every copy with the current time.
Plain cp vs cp -a
mkdir -p src/sub
echo hello > src/sub/notes.txt
touch -d '2020-01-02 03:04:05 UTC' src/sub/notes.txt
cp src/sub/notes.txt plain.txt
cp -a src/sub/notes.txt archived.txt
for f in plain.txt archived.txt; do
if [ "$f" -nt src/sub/notes.txt ]; then echo "$f: new timestamp"; else echo "$f: $(date -u -r "$f" '+%F %T')"; fi
done
cp src copy-plain; echo "exit: $?"
cp -a src copy-a; find copy-a | sortOutput
plain.txt: new timestamp archived.txt: 2020-01-02 03:04:05 cp: -r not specified; omitting directory 'src' exit: 1 copy-a copy-a/sub copy-a/sub/notes.txt
Plain cp gives the file the time of the copy and refuses the directory; cp -a keeps the 2020 timestamp and copies the tree recursively.
What -a turns on
| Option | Meaning |
|---|---|
| -a, --archive | Same as -dR --preserve=all |
| -R, -r, --recursive | Copy directories recursively |
| -d | Copy symbolic links as links (--no-dereference --preserve=links) |
| -p | Same as --preserve=mode,ownership,timestamps |
| --preserve=all | Also SELinux context and xattr; failures to keep those are not fatal |
| -u, --update | Copy only when the source is newer than the destination |
| -n, --no-clobber | Do not overwrite existing files |
| -T, --no-target-directory | Treat DEST as the target itself, never as a directory to copy into |
On macOS and the BSDs cp -a exists too and is equivalent to -RpP: recursive, preserve attributes, do not follow links. It is not in POSIX, which defines only -R and -p, so very old or minimal systems may lack it.
The existing-destination pitfall
cp -a src dest behaves differently depending on whether dest already exists:
mkdir -p src
echo one > src/a.txt
cp -a src dest
cp -a src dest
find dest | sort
echo '--- contents only'
cp -a src/. dest2
find dest2 | sortOutput
dest dest/a.txt dest/src dest/src/a.txt --- contents only dest2 dest2/a.txt
The second run copied src into dest, producing dest/src. Writing src/. copies the contents, so the command gives the same result every time. rsync -a has the same distinction through its trailing slash rule.
Platform notes
- In Git Bash on Windows, permission bits are emulated, so
-amostly preserves timestamps; ownership is meaningless there, and symbolic links are copied as regular files unless native symlinks are enabled. - Preserving ownership needs root. As a normal user
cp -agives the copies your user and group. cp -ashows no progress and restarts from zero if interrupted. For large or remote copies,rsync -acan resume and skip unchanged files.- Combine with
-vto list each copied path, or-nto avoid overwriting files that are already in the destination.
FAQ
What is the difference between cp -a and cp -r?
cp -r copies the tree, but the copies get the current time and your default ownership and mode. cp -a is -dR --preserve=all: it also keeps timestamps, mode, ownership when allowed, symbolic links as links, hard links and extended attributes.
Why does cp -a src dest create dest/src?
When dest already exists as a directory, cp copies src into it. On the first run dest does not exist and becomes the copy; on the second run you get dest/src. Use cp -a src/. dest to copy the contents, or GNU cp -T to treat dest as the target itself.
Does cp -a keep the owner of the files?
Only when you are allowed to set it, which in practice means running as root. As a normal user the copies belong to you and cp -a does not fail because of it.