如何使用Docker cp将多个文件从容器复制到主机

d5vmydt9  于 2022-11-22  发布在  Docker
关注(0)|答案(5)|浏览(308)

我 想 使用 通配符 从 容器 中 的 目录 选择 多 个 文件 , 并 使用 Docker cp 将 这些 文件 从 容器 复制 到 Docker 主机 。
我 不 知道 docker cp 是否 支持 使用 通配符 。

docker cp fd87af99b650:/foo/metrics.csv* /root/metrices_testing/

中 的 每 一 个
这 将 导致 错误 metrics.csv*: no such file or directory
我 遇到 了 一 个 例子 , 其中 for loop 被 用来 选择 一些 文件 , 然后 发送 到 容器 , 但 我 想 把 文件 从 容器 传输 到 主机 , 并 希望 在 Docker 主机 上 完成 这 一 点 , 因为 脚本 只 在 主机 上 运行 。
首先 使用 docker exec 选择 文件 , 然后 使用 docker cp 复制 它们 , 这 是 一 个 选项 , 但 这 是 一 个 两 步 的 过程 。
有人 能 帮 我 一 步 到位 吗 ?
编辑 :
我 试 过 了 。 只 差 一 步 就 失败 了 。

# for f in $(docker exec -it SPSRS bash -c "ls /opt/tpa/logs/metrics.csv*");
     do docker cp SPSRS:$f /root/metrices_testing/;
 done

: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-08:45
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-09:00
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-09:15
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-09:30
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-09:45
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-10:00
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-10:15
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-10:30
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-10:45
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-11:00
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-11:15
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-11:30
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-11:45
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-12:00
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-12:15
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-12:30
: no such file or directory lstat /docker/overlay2/193d2ad0d8d087377e3b96cbfb672b0e39132ae5e961872127614c9396f8c068/merged/opt/SPS_18_5_R1/logs/metrics.csv.2018.07.10-12:45

格式

imzjd6km

imzjd6km1#

事实上你的解决方案可以使你的目标只需要稍微改变一下:

for f in $(docker exec -it SPSRS bash -c "ls /opt/tpa/logs/metrics.csv*"); do docker cp SPSRS:$f /root/metrices_testing/; done
for f in $(docker exec SPSRS bash -c "ls /opt/tpa/logs/metrics.csv*"); do docker cp SPSRS:`echo $f | sed 's/\r//g'` /root/metrices_testing/; done

这是因为docker exec SPSRS bash -c "ls /opt/tpa/logs/metrics.csv*"在每个匹配的字符串中都有\r,所以最后cp在容器中找不到文件。
因此,我们使用echo $f | sed 's/\r//g'来去掉每个文件名的\r,这可以使您工作。

**注意:**对于alpine,我们需要使用sh来替换bash,同时,应删除-it,以避免在alpine中使用彩色打印引入一些不可见字符,如^[[0;0m等。

0lvr5msh

0lvr5msh2#

Docker cp命令支持复制文件夹中的所有内容

docker cp -a container-id:/opt/tpa/logs/  /root/testing/

在上面的示例中,将文件从容器文件夹/opt/tpa/logs复制到本地计算机/root/testing/文件夹。这里,/logs/中的所有文件都将被复制到本地。这里的技巧是使用**-a选项沿着docker cp**

apeeds0o

apeeds0o3#

Docker cp仍然不支持通配符。但是你可以在Docker文件中以如下方式使用它们:

COPY hom* /mydir/        # adds all files starting with "hom"
COPY hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

参考:https://docs.docker.com/engine/reference/builder/#copy

gab6jxml

gab6jxml4#

在容器 * 内 * 运行此程序:

dcp() {
  if [ "$#" -eq 1 ]; then
    printf "docker cp %q .\n" "$(hostname):$(readlink -e "$1")"
  else
    local archive="$(mktemp -t "export-XXXXX.tgz")"
    tar czf "$archive" "$@" --checkpoint=.52428800
    printf "docker exec %q cat %q | tar xvz -C .\n" "$(hostname)" "$archive"
  fi
}

然后选择要复制出的文件:

dcp /foo/metrics.csv*

它将在容器内创建一个存档文件,并发出一个命令供您运行。在主机上运行该命令。
例如:

docker exec 1c75ed99fa42 cat /tmp/export-x9hg6.tgz | tar xvz -C .

或者,我想您也可以不使用临时存档:

dcp() {
  if [ "$#" -eq 1 ]; then
    printf "docker cp %q .\n" "$(hostname):$(readlink -e "$1")"
  else
    printf "docker exec %q tar czC %q" "$(hostname)" "$PWD"
    printf " %q" "$@"
    printf " | tar xzvC .\n"
  fi
}

将为您生成一个命令,例如:

docker exec 1c75ed99fa42 tar czC /root .cache .zcompdump .zinit .zshrc .zshrc.d foo\ bar | tar xzvC .

你甚至不需要化名,这只是一个方便。

n1bvdmb6

n1bvdmb65#

docker cp接受文件或tar归档文件,因此您可以将list of files provided as arguments打包到tar归档文件return the archive to stdout,然后通过管道连接到docker cp

#!/bin/bash

if [[ "$#" -lt 2 || "$1" == "-h" || "$1" == "--help" ]]; then
    printf "Copy files to docker container directory.\n\n"
    echo "Usage: $(basename $0) files... container:directory"
    exit 0
fi

SOURCE="${*%${!#}}"
TARGET="${@:$#}"

tar cf - $SOURCE | docker cp - $TARGET

相关问题