Docker

如何在 Dockerfile 中複製具有多個副檔名的文件?

  • March 14, 2021

這種複制具有多個副檔名的文件的語法(每個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 中複製具有多個副檔名的文件?

DockerfileRUN指令中的命令使用 執行/bin/sh,這可能不支持大括號擴展(您參考的文章明確討論了bash)。

您可以嘗試以下任何方法:

  1. 設置bashRUN使用的 shell SHELL(假設您已經在基礎映像中安裝了 bash 或使用之前的RUN指令):
SHELL ["/bin/bash", "-c"]
RUN cp /tmp/*.{foo,bar} ./ 
  1. 顯式呼叫 bash:
RUN ["/bin/bash", "-c", "cp /tmp/*.{foo,bar} ./"]
  1. 根本不使用大括號擴展:
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
%

引用自:https://unix.stackexchange.com/questions/639161