# docker container cp

## 用法

```shellscript
docker container cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
docker container cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
```

### 别名

`docker cp` 工具将 `SRC_PATH` 的内容复制到 `DEST_PATH`。 你可以从容器的文件系统复制到本地机器，也可以反向操作，从本地文件系统复制到容器。 如果为 `SRC_PATH` 或 `DEST_PATH` 指定了 `-`，你还可以从 STDIN 流式传输 tar 归档文件，或输出到 STDOUT。

容器可以是正在运行的，也可以是已停止的。 `SRC_PATH` 或 `DEST_PATH` 可以是文件或目录。

`docker cp` 命令假定容器路径是相对于容器的 `/`（根）目录的。这意味着提供开头的正斜杠是可选的；该命令将 `compassionate_darwin:/tmp/foo/myfile.txt` 和 `compassionate_darwin:tmp/foo/myfile.txt` 视为相同。

本地机器路径可以是绝对路径或相对路径。该命令将本地机器的相对路径解释为相对于运行 `docker cp` 命令时的当前工作目录。

`cp` 命令的行为类似于 Unix `cp -a` 命令，即递归复制目录，并尽可能保留权限。所有权被设置为目标位置的用户和主组。例如，复制到容器中的文件将以 root 用户的 UID:GID 创建。复制到本地机器的文件将以调用 `docker cp` 命令的用户的 UID:GID 创建。但是，如果你指定了 `-a` 选项，`docker cp` 会将所有权设置为源位置的用户和主组。

如果你指定了 `-L` 选项，`docker cp` 会跟随 `SRC_PATH` 中的任何符号链接。`docker cp` 不会为不存在的 `DEST_PATH` 创建父目录。

假设路径分隔符为 `/`，第一个参数为 `SRC_PATH`，第二个参数为 `DEST_PATH`，其行为如下：

* **`SRC_PATH` 指定一个文件**
  * **`DEST_PATH` 不存在** 文件将保存到在 `DEST_PATH` 处创建的文件中。
  * **`DEST_PATH` 不存在且以 `/` 结尾** 错误情况：目标目录必须存在。
  * **`DEST_PATH` 存在且是一个文件** 目标文件的内容将被源文件的内容覆盖。
  * **`DEST_PATH` 存在且是一个目录** 文件将使用 `SRC_PATH` 的 basename 复制到此目录中。
* **`SRC_PATH` 指定一个目录**
  * **`DEST_PATH` 不存在** `DEST_PATH` 将被创建为一个目录，并将源目录的内容复制到此目录中。
  * **`DEST_PATH` 存在且是一个文件** 错误情况：无法将目录复制到文件。
  * **`DEST_PATH` 存在且是一个目录**
    * **`SRC_PATH` 不以 `/.` 结尾（即：斜杠后跟点）** 源目录将被复制到此目录中。
    * **`SRC_PATH` 以 `/.` 结尾（即：斜杠后跟点）** 源目录的内容将被复制到此目录中。

该命令要求 `SRC_PATH` 和 `DEST_PATH` 根据上述规则存在。 如果 `SRC_PATH` 在本地且是一个符号链接，默认情况下会复制符号链接本身，而不是其目标。要复制链接目标而不是链接本身，请指定 `-L` 选项。

冒号 (`:`) 用作 `CONTAINER` 与其路径之间的分隔符。你也可以在指定本地机器上的 `SRC_PATH` 或 `DEST_PATH` 路径时使用 `:`，例如 `file:name.txt`。如果你在本地机器路径中使用了 `:`，则必须显式指定相对路径或绝对路径，例如：`/path/to/file:name.txt` 或 `./file:name.txt`。

## 选项

<table><thead><tr><th width="188.73046875">选项</th><th>描述</th><th data-hidden>默认值</th></tr></thead><tbody><tr><td><code>-a, --archive</code></td><td>归档模式（复制所有 uid/gid 信息）</td><td></td></tr><tr><td><code>-L, --follow-link</code></td><td>始终跟随 <code>SRC_PATH</code> 中的符号链接</td><td></td></tr><tr><td><code>-q, --quiet</code></td><td>抑制复制过程中的进度输出。如果未连接终端，则自动抑制进度输出</td><td></td></tr></tbody></table>

## 示例

将本地文件复制到容器中：

```shellscript
docker cp ./some_file CONTAINER:/work
```

从容器复制文件到本地路径：

```shellscript
docker cp CONTAINER:/var/logs/ /tmp/app_logs
```

将容器中的文件复制到 stdout。注意 `cp` 命令会产生一个 tar 流：

```shellscript
docker cp CONTAINER:/var/logs/app.log - | tar x -O | grep "ERROR"
```

无法复制某些系统文件，例如 `/proc`、`/sys`、`/dev` 下的资源，以及容器中由用户创建的挂载点下的文件。但是，你仍然可以通过在 `docker exec` 中手动运行 `tar` 来复制此类文件。以下两个示例以不同方式实现相同的功能（假设 `SRC_PATH` 和 `DEST_PATH` 都是目录）：

```shellscript
docker exec CONTAINER tar Ccf $(dirname SRC_PATH) - $(basename SRC_PATH) | tar Cxf DEST_PATH -

tar Ccf $(dirname SRC_PATH) - $(basename SRC_PATH) | docker exec -i CONTAINER tar Cxf DEST_PATH -
```

将 `-` 用作 `SRC_PATH` 时，会将 STDIN 的内容作为 tar 归档文件流式传输。该命令会将 tar 的内容提取到容器文件系统的 `DEST_PATH` 中。在这种情况下，`DEST_PATH` 必须指定一个目录。

将 `-` 用作 `DEST_PATH` 时，会将资源的内容作为 tar 归档文件流式传输到 STDOUT。
