1.介绍
1.1 官方描述翻译
docker cp
工具将SRC_PATH
的内容复制到DEST_PATH
。你可以从容器的文件系统复制到本地机器,或者反过来,从本地文件系统复制到容器。如果SRC_PATH
或DEST_PATH
指定为**-**,你还可以从STDIN
流式传输tar存档,或者传输到STDOUT
。CONTAINER
可以是正在运行的或已停止的容器。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
的基本名复制到此目录中
- 文件将使用
SRC_PATH
指定目录DEST_PATH
不存在DEST_PATH
被创建为目录,并将源目录的内容复制到此目录中
DEST_PATH
存在且是文件- 错误条件:不能将目录复制到文件中
DEST_PATH
存在且是目录SRC_PATH
不以/.结束(即:斜杠后跟点)- 源目录被复制到此目录中
SRC_PATH
以/.结束(即:斜杠后跟点)- 源目录的内容被复制到此目录中
- 该命令要求
SRC_PATH
和DEST_PATH
根据上述规则存在。如果SRC_PATH
是本地的且是一个符号链接,那么默认复制的是符号链接,而不是目标。要复制链接目标而不是链接,请指定-L选项。
冒号(:)用作CONTAINER
和其路径之间的分隔符。你还可以在本地机器上指定路径时使用:,例如file:name.txt
。如果你在本地机器路径中使用:,你必须明确指定相对路径或绝对路径。
1.2 描述总结
docker cp 工具
docker cp工具允许你从容器复制文件到本地主机,或从本地主机复制文件到容器中。这不仅适用于正在运行的容器,而且适用于已停止的容器。
容器路径
docker cp默认容器路径是相对于容器的根目录(/),这意味着,compassionate_darwin:/tmp/foo/myfile.txt
和compassionate_darwin:tmp/foo/myfile.txt
是等效的。
本地路径
本地路径可以是相对路径或绝对路径。如果是相对路径,就相当于运行docker cp命令的工作目录。
复制的内容
- 如果
SRC_PATH
指定一个文件,并且DEST_PATH
不存在,docker cp会创建DEST_PATH
并保存文件。 - 如果
SRC_PATH
是一个文件,而DEST_PATH
是一个已存在的文件,则DEST_PATH
会被SRC_PATH
的内容覆盖。 - 如果
SRC_PATH
是一个文件,而DEST_PATH
是一个目录,文件会被复制到DEST_PATH
目录中,文件名保持不变。 - 如果
SRC_PATH
是一个目录,docker cp
会递归复制目录中的所有内容。
权限与所有权
复制过程会尽可能保留文件和目录的权限。默认情况下,所有权会被设置为目标处的用户和主要组。但是,使用-a
选项会保留源文件的所有权。
符号链接
默认情况下,如果SRC_PATH
是一个符号链接,docker cp会复制链接本身,而不是链接指向的文件。使用-L
选项会复制链接指向的文件。
使用冒号
冒号(:)在docker cp命令中有特殊的意义。它用作容器名和容器内路径之间的分隔符。如果在本地路径中使用冒号,必须明确指定是相对路径还是绝对路径。
特殊情况与错误条件
- 如果
DEST_PATH
以/结尾但不存在,这会导致错误,因为目标目录必须存在。 - 如果
SRC_PATH
是目录,而DEST_PATH
是已存在的文件,这也是一个错误条件,不能将目录复制到文件中。 - docker cp不会为
DEST_PATH
创建不存在的父目录。
1.3 选项
Option | Short | Default | Description |
---|---|---|---|
–archive | -a | 归档模式(复制所有uid/gid信息)。 | |
–follow-link | -L | 在SRC_PATH 中总是跟随符号链接。 | |
–quiet | -q | 复制过程中抑制进度输出。如果没有终端连接,进度输出会自动被抑制。 |
我使用的docker版本是20.10.24,已经没有-q
这个参数了,你可以使用docker cp --help
来查看你的版本是否包含。
2.使用示例
选择一个容器做示例,获取容器id
docker ps
我的容器id是:1fd731e7cc4e,这是我的工作目录下的信息我现在我使用current.env作为示例,
宿主机复制文件到容器:
docker cp current.env 1fd731e7cc4e:/usr/local/openresty/
容器中即可看到文件:
容器复制文件到宿主机:
docker cp 1fd731e7cc4e:/usr/local/openresty/resty.index ./
当前工作目录查看文件(ll或ls):
带参数的示例
给logs创建一个软链接
ln -s target_file symlink
结果如下:复制到容器自定目录下:
docker cp -a -L logslink 1fd731e7cc4e:/usr/local/openresty/
结果如下:如果没有-L参数,复制的就是链接本身:
ln -s logs logslink2
docker cp -a logslink2 1fd731e7cc4e:/usr/local/openresty/
结果如下:
不可复制文件解析示例:
Docker容器中一些特定的系统文件,例如位于/proc
, /sys
, /dev
, 和 tmpfs的资源,以及用户在容器中创建的挂载点,是无法通过docker cp命令直接复制的。
使用docker cp命令时,如果将目标设为连字符-
,那么它会将容器中所复制的文件的输出以tar流的形式流到标准输出(stdout)。对于在不实际将文件复制到本地文件系统的情况下进一步处理或过滤文件内容非常有用。
以挂载点/usr/local/openresty/nginx/logs
为例:
docker cp 1fd731e7cc4e:/usr/local/openresty/nginx/logs/error.log - | tar x -O | grep "start"
结果如下:如果需要复制,官方提供了tar与docker exec配合复制的案例,这里就不多示例了
官方文档地址: docker cp
生活是属于每个人自己的感受,不属于任何别人的看法 --余华《活着》