3

In a Dockerfile, I want to use process substitution:

RUN echo <(echo '$DATA:'"$DATA") 

But docker build runs every RUN command with /bin/sh. Apparently being run as sh causes bash to switch to POSIX mode, which does not allow process substitution:

/bin/sh: -c: line 0: syntax error near unexpected token `(' 

I tried switching off POSIX mode:

RUN set +o posix && echo <(echo '$DATA:'"$DATA") 

But it seems the syntax error happens even before the first command is run. Same if I replace && with ;.

Note that the command (even the one that I used as a simplified example here) contains both single and double quotes, so I can't simply prepend bash -c.

The used shell is actually a bash, but it is invoked as /bin/sh by docker:

Step 7 : RUN ls -l /bin/sh ---> Running in 93a9809e12a7 lrwxrwxrwx 1 root root 9 Dec 28 03:38 /bin/sh -> /bin/bash 

2 Answers 2

1

If you are sure you have bash in your image being built, then you can change the shell invokation by using the SHELL command, which I described in another question.

You can use SHELL [ "/bin/bash", "-c" ]. Consider:

$ docker build --no-cache - < <(echo ' > FROM fedora > RUN cat <(echo hello world) > ') Sending build context to Docker daemon 2.048kB Step 1/2 : FROM fedora ---> ef49352c9c21 Step 2/2 : RUN cat <(echo hello world) ---> Running in 573730ced3a3 /bin/sh: -c: line 0: syntax error near unexpected token `(' /bin/sh: -c: line 0: `cat <(echo hello world)' The command '/bin/sh -c cat <(echo hello world)' returned a non-zero code: 1 $ docker build --no-cache - < <(echo ' > FROM fedora > SHELL ["/bin/bash", "-c"] > RUN cat <(echo hello world) > ') Sending build context to Docker daemon 2.048kB Step 1/3 : FROM fedora ---> ef49352c9c21 Step 2/3 : SHELL ["/bin/bash", "-c"] ---> Running in e78260e6de42 Removing intermediate container e78260e6de42 ---> ff6ec782a9f6 Step 3/3 : RUN cat <(echo hello world) ---> Running in afbb42bba5b4 hello world Removing intermediate container afbb42bba5b4 ---> 25f756dcff9b Successfully built 25f756dcff9b 
Sign up to request clarification or add additional context in comments.

3 Comments

looks like StackOverflow's syntax highlighting broke on this. I'm not sure if or how I could fix that lol
Easiest fix is to just turn it off; see edit doing so. :) --- btw, if you really want to use the older four-space-indent syntax, <!-- language: none --> prior to an indented block will do the same.
Heh I just used "older four space indent syntax" because that's what I knew StackOverflow used. Is there another better syntax now?
0

Assuming your sh is not bash, you can't use process substitution in shell mode directly; you need to spawn a bash session (non-login, non-interactive here):

RUN [ "/bin/bash", "-c", "echo <(echo '$DATA:'\"$DATA\")" ] 

Here i have used the json (aka exec) form to make sure the quotes are easily managed, here you just need to escape quotes around $DATA: \"$DATA\" -- to prevent json interpretation beforehand.


If your sh is in fact bash, this should do:

RUN "echo <(echo '$DATA:'"$DATA")" 

Also this just outputs the file descriptor, i am not rally sure about your plan.

4 Comments

It is in fact bash, it's just not called as such. I made that clear in an edit.
That second RUN command gives me container_linux.go:247: starting container process caused "exec: \"echo <(echo '$DATA:'\\\"$DATA\\\")\": executable file not found in $PATH". Outputting the file descriptor is just to show that it works.
@AndreKR Ooops, my bad. Check now.
That gives: /bin/sh: echo <(echo ':'): command not found Otherwise it is virtually identical to my non-working example.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.