0

This syntax of copying files with multiple extensions (per Copying files with multiple extensions) works fine in a regular desktop environment:

$ mkdir /tmp/baz && cd /tmp/baz
$ touch /tmp/file.foo
$ touch /tmp/file.bar
$ cp /tmp/*.{foo,bar} ./
$

But this doesn't seem to work in a 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

Oddly, if I enter a running container, the exact same cp syntax works fine.

How can I copy files with multiple extensions in a Dockerfile?

1 Answer 1

1

Commands in a Dockerfile RUN instruction are run using /bin/sh, which may not support brace expansion (the post you refer to explicitly talks about bash).

You can try any of the following:

  1. Set bash as the shell for RUN using SHELL (assuming you already have bash installed in the base image or using a previous RUN instruction):

    SHELL ["/bin/bash", "-c"]
    RUN cp /tmp/*.{foo,bar} ./ 
    
  2. Call bash explicitly:

    RUN ["/bin/bash", "-c", "cp /tmp/*.{foo,bar} ./"]
    
  3. Just not use brace expansion at all:

    RUN cp /tmp/*.foo /tmp/*.bar ./
    

Oddly, if I enter a running container, the exact same cp syntax works fine.

Your running container might be running bash as the default shell. This needn't always be the case:

% 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
%

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .