跳到主要内容

在容器和本地文件系统之间复制文件/文件夹

概要

podman cp [选项][*容器*:]源文件路径 [容器:]目标文件路径

podman container cp [选项][*容器*:]源文件路径 [容器:]目标文件路径

说明

podman cp 命令允许将 源文件路径 的内容复制到 目标文件路径。文件可以从容器复制到本地机器,也可以从本地机器复制到容器,或者在两个容器之间复制。 如果为 SRC_PATHDEST_PATH 指定了 -,则还可以从 STDIN 接收或向 STDOUT 输出 tar 归档文件。

容器可以是运行状态或停止状态,而 源文件路径目标文件路径 可以是文件或目录。

重要提示:podman cp 命令假定容器路径是相对于容器根目录(/)的,这意味着提供初始的正斜杠是可选的,因此将 compassionate_darwin:/tmp/foo/myfile.txtcompassionate_darwin:tmp/foo/myfile.txt 视为相同的。

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

假设路径分隔符为 /,第一个参数为 源文件路径,第二个参数为 目标文件路径,则行为如下:

源文件路径 指定一个文件:

  • 目标文件路径 不存在
    • 文件将被保存到在 目标文件路径 创建的新文件中(请注意,父目录必须存在)。
  • 目标文件路径 存在且是一个文件
    • 目标文件将被源文件的内容覆盖。
  • 目标文件路径 存在且是一个目录
    • 文件将被复制到此目录中,并使用从 源文件路径 获取的基本名称。

源文件路径 指定一个目录:

  • 目标文件路径 不存在
    • 创建一个 目标文件路径 作为目录,并将源目录的内容复制到这个目录中。
  • 目标文件路径 存在且是一个文件
    • 错误条件:无法将一个目录复制到一个文件中。
  • 目标文件路径 存在且是一个目录
    • 源文件路径/ 结尾
      • 源目录将被复制到这个目录中。
    • 源文件路径/. 结尾(即斜杠后跟一个点)
      • 源目录的内容将被复制到这个目录中。

该命令要求根据以上规则 源文件路径目标文件路径 必须存在。

如果 源文件路径 是本地的并且是一个符号链接,则默认情况下将复制符号链接的目标。

冒号 ( : ) 被用作容器与其路径之间的分隔符,它也可以用于在本地机器上指定 src_pathdest_path 的路径,例如 file:name.txt

重要提示:在本地机器路径中使用 冒号 ( : ) 时,必须明确指定相对路径或绝对路径,例如:/path/to/file:name.txt./file:name.txt

使用 - 作为 src_path 会将 STDIN 的内容作为 tar 归档文件进行流处理。命令会将 tar 的内容提取到容器中的 DEST_PATH。在这种情况下,dest_path 必须指定一个目录。使用 - 作为 dest_path 会将资源(可以是目录)的内容作为 tar 归档文件流处理到 STDOUT

请注意,当从正在运行的非 root 容器复制文件时,podman cp 会忽略权限错误。非 root 容器内部的 TTY 设备属于主机上的 root 用户,因此无法在容器的用户命名空间中读取它们。

此外,请注意 podman cp 不支持通配符(例如 cp dir/*.txt)。要从主机复制多个文件到容器,请使用 xargs(1)find(1)(或用于命令串联的类似工具)与 podman cp 结合使用。要从容器复制多个文件到主机,请使用 podman mount CONTAINER 并操作返回的挂载点(请参阅下面的替代方案)。

选项

--archive, -a

归档模式(复制所有 UID/GID 信息)。 当设置为 true 时,复制到容器的文件将更改其所有权为主要 UID/GID。 当设置为 false 时,保持从归档源中的 UID/GID 而不是将它们更改为目标容器的主要 UID/GID。 默认值为 true

--overwrite

允许目录被非目录覆盖,反之亦然。默认情况下,当尝试覆盖时(例如,用一个目录覆盖一个常规文件),podman cp 会报错。

替代方案

Podman 在实现主机与容器之间复制文件的功能时,除了 podman cp 之外,还具有更强的能力。

使用标准的 podman-mount(1)podman-unmount(1) 命令可以利用整个 Linux 工具链,而不仅仅是 cp 命令。

通过几个简单的命令,就可以实现将内容从容器中复制出来或复制到容器中。例如:

要将容器中的 /etc/foobar 目录复制到主机上的 /tmp 目录,可以执行以下命令:

mnt=$(podman mount CONTAINERID)
cp -R ${mnt}/etc/foobar /tmp
podman umount CONTAINERID

要将 tar 包解压到容器中,可以执行以下命令:

mnt=$(podman mount CONTAINERID)
tar xf content.tgz -C ${mnt}
podman umount CONTAINERID

要在没有安装 dnf 的容器中安装软件包,可以执行以下命令:

mnt=$(podman mount CONTAINERID)
dnf install --installroot=${mnt} httpd
chroot ${mnt} rm -rf /var/log/dnf /var/cache/dnf
podman umount CONTAINERID

通过使用 podman mountpodman umount,可以使用所有标准的 Linux 工具来在容器内外移动文件,而不仅仅是 cp 命令。

EXAMPLES

示例

从主机复制文件到容器

podman cp /myapp/app.conf containerID:/myapp/app.conf

这个命令将主机上的 /myapp/app.conf 文件复制到容器 containerID/myapp/app.conf 路径下。

从一个容器复制文件到另一个容器的目录

podman cp containerID1:/myfile.txt containerID2:/tmp

这个命令将容器 containerID1 中的 /myfile.txt 文件复制到容器 containerID2/tmp 目录下。

从容器复制目录到主机目录

podman cp containerID:/myapp/ /myapp/

这个命令将容器 containerID 中的 /myapp/ 目录复制到主机的 /myapp/ 目录下。

复制容器目录内容到主机目录

podman cp containerID:/home/myuser/. /home/myuser/

这个命令将容器 containerID 中的 /home/myuser/ 目录下的所有内容复制到主机的 /home/myuser/ 目录下,注意结尾的 . 表示复制目录内容而非目录本身。

将一个容器中的目录复制到另一个容器的目录

podman cp containerA:/myapp containerB:/newapp

这个命令将容器 containerA 中的 /myapp 目录复制到容器 containerB/newapp 目录下。

从标准输入流复制 tar 归档到容器

podman cp - containerID:/myfiles.tar.gz < myfiles.tar.gz

这个命令将本地文件 myfiles.tar.gz 作为 tar 归档,通过标准输入流复制到容器 containerID/myfiles.tar.gz 路径下。注意 - 符号的使用,它表示从标准输入读取数据。

另请参阅

podman(1), podman-mount(1), podman-unmount(1)

这些命令和工具与 podman cp 相关,提供了不同的功能来管理和操作容器。podman 是主要的容器管理工具,而 podman-mountpodman-unmount 则用于挂载和卸载容器的文件系统,允许用户直接访问容器内部的文件系统。这些工具提供了更灵活的方式来处理容器和主机之间的文件交互。