Bash brace expansion not working on Dockerfile RUN command
Asked Answered
M

2

27

I'm running the following RUN command in my Dockerfile, expecting a "logs" directory to be created under each of the listed subdirectories:

RUN mkdir -p /opt/seagull/{diameter-env,h248-env,http-env,msrp-env,octcap-env,radius-env,sip-env,synchro-env,xcap-env}/logs

But when I check the image, I see a directory literally called "{diameter-env,h248-env,http-env,msrp-env,octcap-env,radius-env,sip-env,synchro-env,xcap-env}" created under /opt/seagull, instead of brace expansion taking place.

What could I be doing wrong?

Ministrant answered 20/10, 2016 at 21:13 Comment(2)
I don't know one way or the other, but does RUN run under bash?Klinger
It turns out, it depends on whether you're using the shell form or the exec form. See my answer below.Ministrant
M
45

You're not using brace expansion, because you're not using Bash. If you look at the documentation for the RUN command:

RUN (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)

And also:

Note: To use a different shell, other than ‘/bin/sh’, use the exec form passing in the desired shell. For example, RUN ["/bin/bash", "-c", "echo hello"]

So, just change the command to use the exec form and explicitly use a Bash shell:

RUN [ "/bin/bash", "-c", "mkdir -p /opt/seagull/{diameter-env,h248-env,http-env,msrp-env,octcap-env,radius-env,sip-env,synchro-env,xcap-env}/logs" ]
Ministrant answered 20/10, 2016 at 21:16 Comment(6)
Thanks! I can't believe I spent 45 minutes on this, trying different escaping techniques, checking default bash settings, etc.Ministrant
Wait, what? You've answered you own question, and you're thanking yourself for it...?Klinger
Yes! :) It's been an exhausting day, and I needed to thank myself for finally RTFM. Also, stackoverflow.com/help/self-answerMinistrant
It's not the answering own question that confused the hell out of me, it was just the comment, but hey, if it's deserved ;DKlinger
Could you not ln -f /bin/bash /bin/sh, I believe the reason is that typically nowadays /bin/sh is a symlink to /bin/dash.Plethora
Important note from the official documentation: The exec form is parsed as a JSON array, which means that you must use double-quotes (“) around words not single-quotes (‘).Yen
E
15

If /bin/bash is available in your image, you can change the shell that the docker build system uses to execute your RUN command, like this:

SHELL ["/bin/bash", "-c"]

Now, your RUN command should work unchanged.

Eulogium answered 4/10, 2020 at 22:7 Comment(1)
So worth the scroll past the accepted answer.Orenorenburg

© 2022 - 2024 — McMap. All rights reserved.