# cp

_Peios / Using Peios / Peiosutils / Files and directories_

> Copy files and directories — including how a copy gets its security descriptor and the --preserve family that carries attributes from the source.

`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:

| Option | Effect |
|---|---|
| `-r`, `-R`, `--recursive` | Copy directories, and everything inside them, recursively. |
| `-a`, `--archive` | A 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](/peios/security-fundamentals/security-descriptors/overview.md) — 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:

| Attribute | What it carries from the source |
|---|---|
| `owner` | The owner SID. |
| `dacl` | The whole DACL — every access rule on the file, inherited rules included. |
| `sacl` | The whole SACL — the audit rules and the integrity label. |
| `daclni` | The DACL with **inherited** rules stripped out — only the rules set explicitly on the source. |
| `saclni` | The SACL with inherited rules stripped out. |
| `timestamps` | The access and modification times. |
| `links` | The hard-link structure — files hard-linked together in the source stay hard-linked in the copy. |
| `security` | The `security.peios.*` extended attributes (other than the descriptor itself). |
| `xattrs` | All other extended attributes. |

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

| Option | Preserves |
|---|---|
| `-p` | Timestamps only. |
| `--preserve` | Timestamps only — the same as `-p`. |
| `--preserve=LIST` | Exactly the comma-separated attributes you name. |
| `--preserve-all` | Every attribute in the table above. |
| `--sd` | `owner`, `dacl`, `sacl` — the **full security descriptor**, copied verbatim. |
| `--sd-explicit` | `owner`, `daclni`, `saclni` — the source's **explicitly set** rules only. |
| `--no-preserve=LIST` | Turns 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](/peios/security-fundamentals/security-descriptors/inheritance.md).

### 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.

| Option | Effect |
|---|---|
| `-i`, `--interactive` | Ask before overwriting an existing file. |
| `-n`, `--no-clobber` | Never 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`, `--force` | If an existing destination cannot be opened for writing, remove it and try the copy again. |
| `--remove-destination` | Remove the destination *before* opening it, always — contrast `--force`, which only removes on failure. |
| `-b`, `--backup[=CONTROL]` | Before overwriting, make a backup of the destination. |

## Symbolic links in the source

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

| Option | Effect |
|---|---|
| `-L`, `--dereference` | Always follow symbolic links — copy the file they point to. |
| `-P`, `--no-dereference` | Never follow symbolic links — copy the link itself. |
| `-H` | Follow only the symbolic links named directly on the command line, not links found while recursing. |
| `-d` | Copy 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.

| Option | Effect |
|---|---|
| `-l`, `--link` | Create a hard link to the source instead of copying its data. |
| `-s`, `--symbolic-link` | Create 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-only` | Create the destination and copy its attributes, but not its data. |

## Other options

| Option | Effect |
|---|---|
| `-t`, `--target-directory=DIR` | Copy every source into `DIR`. Useful when the directory is not the last argument. |
| `-T`, `--no-target-directory` | Treat `dest` as a plain file even if it is a directory. |
| `--parents` | Recreate the source's leading directories under the destination. |
| `-x`, `--one-file-system` | Do not cross into a different file system while recursing. |
| `--strip-trailing-slashes` | Strip any trailing slashes from each source argument before using it. |
| `-v`, `--verbose` | Print each file as it is copied. |
| `--debug` | Explain in detail how each file was copied. Implies `-v`. |
| `--progress` | Show a progress bar. |

## Exit status

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

Related content:

- [mv](/peios/using-peios/peiosutils/files-and-directories/mv.md)
- [Files and directories](/peios/using-peios/peiosutils/files-and-directories/overview.md)
- [Security descriptors](/peios/security-fundamentals/security-descriptors/overview.md)
- [Inheritance](/peios/security-fundamentals/security-descriptors/inheritance.md)
