cp

cp copies files and directories.

cp [options] source dest
cp [options] source... directory
cp [options] -t directory source...

In the first form, cp copies one source to one dest. In the other two, it copies any number of sources into a directory, keeping their names.

$ cp report.txt report-backup.txt
$ cp report.txt notes.txt /home/jack/archive/

Copying directories #

cp refuses to copy a directory unless you ask it to descend into one:

OptionEffect
-r, -R, --recursiveCopy directories, and everything inside them, recursively.
-a, --archiveA faithful recursive copy: copy the whole tree, follow no symbolic links, and preserve every attribute. Equivalent to -d -R --preserve-all.

-a is the option to use when you want the copy to be as close to the original as possible — same structure, same security, same timestamps. A plain -r copies the contents but, as the next section explains, gives the copies fresh security of their own.

What a copy's security descriptor is #

This is the part of cp that is specific to Peios, so it is worth being precise.

Every file carries a security descriptor — the record of who owns it and who may do what to it. When cp copies a file, it creates a new file, and that new file needs a descriptor.

By default, a copy gets a fresh descriptor — it does not inherit the source's. Specifically, a plain cp:

  • gives the copy a descriptor inherited from the destination directory, exactly as if you had created a new file there;
  • makes you the owner of the copy;
  • gives the copy fresh timestamps — the copy's modification time is "now".

This is usually what you want. A file copied into your home directory should be governed by your home directory's rules and owned by you, regardless of where it came from. But when you need the copy to keep something from the source, you ask for it explicitly — with the --preserve family.

The --preserve family #

--preserve carries chosen attributes from the source onto the copy. The attributes you can preserve:

AttributeWhat it carries from the source
ownerThe owner SID.
daclThe whole DACL — every access rule on the file, inherited rules included.
saclThe whole SACL — the audit rules and the integrity label.
daclniThe DACL with inherited rules stripped out — only the rules set explicitly on the source.
saclniThe SACL with inherited rules stripped out.
timestampsThe access and modification times.
linksThe hard-link structure — files hard-linked together in the source stay hard-linked in the copy.
securityThe security.peios.* extended attributes (other than the descriptor itself).
xattrsAll other extended attributes.

You rarely name those individually. These options select sensible sets:

OptionPreserves
-pTimestamps only.
--preserveTimestamps only — the same as -p.
--preserve=LISTExactly the comma-separated attributes you name.
--preserve-allEvery attribute in the table above.
--sdowner, dacl, sacl — the full security descriptor, copied verbatim.
--sd-explicitowner, daclni, saclni — the source's explicitly set rules only.
--no-preserve=LISTTurns the named attributes back off — useful to subtract from a broader option.

--sd versus --sd-explicit #

Both carry the source's security across; they differ in how they treat inherited rules.

  • --sd copies the descriptor exactly — inherited rules and all. The copy ends up with precisely the access rules the source had, even if it lands in a directory that would have handed down something different. Use it when the copy must be a security-exact duplicate.
  • --sd-explicit copies only the rules that were set explicitly on the source, and lets the destination directory supply inheritance for the rest. Use it when copying a file into a different directory and you want the file's own tailored rules to come along while still picking up the new location's inherited rules.

For what "inherited" versus "explicit" means, see Inheritance.

When a preserve cannot be honoured #

A requested preserve is a firm instruction. If cp cannot carry an attribute across — for example, writing the copy's SACL requires the SeSecurityPrivilege privilege, and the caller does not have it — cp treats that as a hard error and the copy fails. It does not quietly produce a copy that is missing what you asked to preserve.

There is one exception, and it is a matter of definition rather than a softening of the rule. security and xattrs name extended attributes, and some filesystems have no extended attributes at all — FAT, 9p, and a squashfs image built without an attribute table are the ones you will meet. Copying from such a filesystem carries nothing, because there was nothing there: the preserve is satisfied vacuously, and the copy succeeds.

That is narrow on purpose. It applies only to reading the source. If the source does have extended attributes and the destination filesystem cannot hold them, the preserve genuinely failed and cp still stops:

# cp -a /home/jack/notes /mnt/usb-fat/
cp: failed to set extended attributes on '/mnt/usb-fat/notes': Operation not supported

The distinction matters most for -a, which requests both attribute classes on every file it touches. Without it, one xattr-less filesystem anywhere in a tree would abort the whole copy partway through.

Overwriting an existing destination #

By default, if the destination already exists, cp overwrites it. These options change that.

OptionEffect
-i, --interactiveAsk before overwriting an existing file.
-n, --no-clobberNever overwrite an existing file; skip it silently.
-u, --update[=WHICH]Overwrite only when the source is newer than the destination. WHICH can be all, none, or older.
-f, --forceIf an existing destination cannot be opened for writing, remove it and try the copy again.
--remove-destinationRemove the destination before opening it, always — contrast --force, which only removes on failure.
-b, --backup[=CONTROL]Before overwriting, make a backup of the destination.

When a source is a symbolic link, cp can copy the link itself or the file it points to.

OptionEffect
-L, --dereferenceAlways follow symbolic links — copy the file they point to.
-P, --no-dereferenceNever follow symbolic links — copy the link itself.
-HFollow only the symbolic links named directly on the command line, not links found while recursing.
-dCopy links as links, and preserve hard-link structure. Short for --no-dereference --preserve=links.

Other ways to copy #

cp can also produce something other than a plain duplicate.

OptionEffect
-l, --linkCreate a hard link to the source instead of copying its data.
-s, --symbolic-linkCreate a symbolic link to the source instead of copying.
--reflink[=WHEN]Make a lightweight copy-on-write clone where the file system supports it. WHEN is always, auto, or never.
--sparse[=WHEN]Control whether runs of zero bytes are stored as holes rather than written out. WHEN is always, auto, or never.
--attributes-onlyCreate the destination and copy its attributes, but not its data.

Other options #

OptionEffect
-t, --target-directory=DIRCopy every source into DIR. Useful when the directory is not the last argument.
-T, --no-target-directoryTreat dest as a plain file even if it is a directory.
--parentsRecreate the source's leading directories under the destination.
-x, --one-file-systemDo not cross into a different file system while recursing.
--strip-trailing-slashesStrip any trailing slashes from each source argument before using it.
-v, --verbosePrint each file as it is copied.
--debugExplain in detail how each file was copied. Implies -v.
--progressShow a progress bar.

Exit status #

CodeMeaning
0Every file was copied successfully.
1A file could not be copied — including a requested --preserve that could not be honoured.

Edit this page