Using the RUN instruction in a Dockerfile with 'source' does not work
Solution 1:
Original Answer
FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
This should work for every Ubuntu docker base image. I generally add this line for every Dockerfile I write.
Edit by a concerned bystander
If you want to get the effect of "use bash
instead of sh
throughout this entire Dockerfile", without altering and possibly damaging* the OS inside the container, you can just tell Docker your intention. That is done like so:
SHELL ["/bin/bash", "-c"]
* The possible damage is that many scripts in Linux (on a fresh Ubuntu install
grep -rHInE '/bin/sh' /
returns over 2700 results) expect a fully POSIX shell at/bin/sh
. The bash shell isn't just POSIX plus extra builtins. There are builtins (and more) that behave entirely different than those in POSIX. I FULLY support avoiding POSIX (and the fallacy that any script that you didn't test on another shell is going to work because you think you avoided basmisms) and just using bashism. But you do that with a proper shebang in your script. Not by pulling the POSIX shell out from under the entire OS. (Unless you have time to verify all 2700 plus scripts that come with Linux plus all those in any packages you install.)
More detail in this answer below. https://stackoverflow.com/a/45087082/117471
Solution 2:
The default shell for the RUN
instruction is ["/bin/sh", "-c"]
.
RUN "source file" # translates to: RUN /bin/sh -c "source file"
Using SHELL instruction, you can change default shell for subsequent RUN
instructions in Dockerfile:
SHELL ["/bin/bash", "-c"]
Now, default shell has changed and you don't need to explicitly define it in every RUN instruction
RUN "source file" # now translates to: RUN /bin/bash -c "source file"
Additional Note: You could also add --login
option which would start a login shell. This means ~/.bashrc
for example would be read and you don't need to source it explicitly before your command