Docker
如何在 Dockerfile 中複製具有多個副檔名的文件?
這種複制具有多個副檔名的文件的語法(每個Copying files with multiple extensions)在正常桌面環境中執行良好:
$ 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 中複製具有多個副檔名的文件?
Dockerfile
RUN
指令中的命令使用 執行/bin/sh
,這可能不支持大括號擴展(您參考的文章明確討論了bash
)。您可以嘗試以下任何方法:
- 設置
bash
為RUN
使用的 shellSHELL
(假設您已經在基礎映像中安裝了 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 %