这种复制具有多个扩展名的文件的语法(每个复制具有多个扩展名的文件)在常规桌面环境中工作正常:
$ mkdir /tmp/baz && cd /tmp/baz
$ touch /tmp/file.foo
$ touch /tmp/file.bar
$ cp /tmp/*.{foo,bar} ./
$
但这似乎在 dockerfile 中不起作用:
# Dockerfile
FROM alpine:3.7 as base
RUN touch /tmp/file.foo
RUN touch /tmp/file.bar
RUN cp /tmp/*.{foo,bar} ./
$ docker build -t tmp:tmp . && docker run -it tmp:tmp
[+] Building 4.0s (7/7) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 149B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/alpine:3.7 0.0s
=> CACHED [1/4] FROM docker.io/library/alpine:3.7 0.0s
=> [2/4] RUN touch /tmp/file.foo 1.1s
=> [3/4] RUN touch /tmp/file.bar 1.1s
=> ERROR [4/4] RUN cp /tmp/*.{foo,bar} ./ 1.5s
------
> [4/4] RUN cp /tmp/*.{foo,bar} ./:
#7 0.844 cp: can't stat '/tmp/*.{foo,bar}': No such file or directory
------
failed to solve with frontend dockerfile.v0: failed to build LLB: executor failed running [/bin/sh -c cp /tmp/*.{foo,bar} ./]: exit code: 1
奇怪的是,如果我进入正在运行的容器,完全相同的cp
语法可以正常工作。
如何在 Dockerfile 中复制具有多个扩展名的文件?
答案1
命令位于DockerfileRUN
指令使用 运行/bin/sh
,它可能不支持大括号扩展(您引用的帖子明确讨论了bash
)。
您可以尝试以下任一方法:
设置
bash
为shellRUN
使用SHELL
(假设您已经在基础映像中安装了 bash 或使用之前的RUN
指令):SHELL ["/bin/bash", "-c"] RUN cp /tmp/*.{foo,bar} ./
显式调用 bash:
RUN ["/bin/bash", "-c", "cp /tmp/*.{foo,bar} ./"]
只是根本不使用大括号扩展:
RUN cp /tmp/*.foo /tmp/*.bar ./
奇怪的是,如果我进入正在运行的容器,完全相同的
cp
语法可以正常工作。
您正在运行的容器可能正在运行 bash 作为默认 shell。情况并不总是如此:
% docker run --rm -it alpine:3.7
/ # echo /tmp/*.{foo,bar} ./
/tmp/*.{foo,bar} ./
/ # exit
% docker run --rm -it ubuntu:20.04
root@f184619a1121:/# echo /tmp/*.{foo,bar} ./
/tmp/*.foo /tmp/*.bar ./
root@f184619a1121:/# exit
%