Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dockerfile: Output of RUN instruction into a Variable

I am writing a dockerfile and want to put the output of the "ls" command into a variable as shown below:

$file = ls /tmp/dir

Here, "dir" only has one file inside it.

The following RUN instruction within a dockerfile is not working

RUN $file = ls /tmp/dir
like image 212
meallhour Avatar asked Dec 10 '15 23:12

meallhour


People also ask

What does run instruction do in Dockerfile?

The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile .

How do I create a Run command in Dockerfile?

The basic syntax for the command is: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] You can run containers from locally stored Docker images. If you use an image that is not on your system, the software pulls it from the online registry.

Can you run Docker commands in Dockerfile?

You can't run Docker commands from a Dockerfile (and shouldn't as a general rule try to run Docker commands from within Docker containers) but you can write an ordinary shell script on the host that runs the docker build && docker run .


3 Answers

You cannot save a variable for later use in other Dockerfile commands (if that is your intention). This is because each RUN happens in a new shell.

However, if you just want to capture the output of ls you should be able to do it in one RUN compound command. For example:

RUN file="$(ls -1 /tmp/dir)" && echo $file

Or just using the subshell inline:

RUN echo $(ls -1 /tmp/dir)

Hope this helps your understanding. If you have an actual error or problem to solve I could expand on this instead of a hypothetical answer.

A full example Dockerfile demonstrating this would be:

FROM alpine:3.7
RUN mkdir -p /tmp/dir && touch /tmp/dir/file1 /tmp//dir/file2
RUN file="$(ls -1 /tmp/dir)" && echo $file
RUN echo $(ls -1 /tmp/dir)

When building you should see steps 3 and 4 output the variable (which contains the list of file1 and file2 creating in step 2):

$ docker build --no-cache -t test .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM alpine:3.7
 ---> 3fd9065eaf02
Step 2/4 : RUN mkdir -p /tmp/dir && touch /tmp/dir/file1 /tmp//dir/file2
 ---> Running in abb2fe683e82
Removing intermediate container abb2fe683e82
 ---> 2f6dfca9385c
Step 3/4 : RUN file="$(ls -1 /tmp/dir)" && echo $file
 ---> Running in 060a285e3d8a
file1 file2
Removing intermediate container 060a285e3d8a
 ---> 2e4cc2873b8c
Step 4/4 : RUN echo $(ls -1 /tmp/dir)
 ---> Running in 528fc5d6c721
file1 file2
Removing intermediate container 528fc5d6c721
 ---> 1be7c54e1f29
Successfully built 1be7c54e1f29
Successfully tagged test:latest
like image 121
Andy Shinn Avatar answered Oct 23 '22 12:10

Andy Shinn


I couldn't get Andy's (or any other) approach to work in the Dockerfile itself, so I set my Dockerfile entrypoint to a bash file containing:

#!/bin/bash
file="$(conda list --explicit)" && echo $file
echo $(conda list --explicit)

Note the second method doesn't render line breaks, so I found the first method - echo via the $file variable - superior.

like image 45
Chris Avatar answered Oct 23 '22 12:10

Chris


Just highlight the answer given in the comments, which is probably the correct one if you are using a modern version of Docker (in my case v20.10.5) and the logs do not show the expected output, when, for example, you run RUN ls.

You should use the option --progress string in the docker build command:

 --progress string         Set type of progress output (auto, plain, tty). Use plain to show container output
                            (default "auto")

For example:

docker build --progress=plain .

In the latest versions of docker, the classic build engine that docker ships with has been upgraded to Builtkit, which displays different information.

You should see output like:

#12 [8/8] RUN ls -alh
#12 sha256:a8cf7b9a7b1f3dc25e3a97700d4cc3d3794862437a5fe2e39683ab229474746c
#12 0.174 total 184K
#12 0.174 drwxr-xr-x    1 root     root        4.0K Mar 28 19:37 .
#12 0.174 drwxr-xr-x    1 root     root        4.0K Mar 28 19:35 ..
#12 0.174 drwxr-xr-x  374 root     root       12.0K Mar 28 19:37 node_modules
#12 0.174 -rw-r--r--    1 root     root        1.1K Mar 28 19:36 package.json
#12 0.174 -rw-r--r--    1 root     root         614 Mar 28 15:48 server.js
#12 0.174 -rw-r--r--    1 root     root      149.5K Mar 28 16:54 yarn.lock
#12 DONE 0.2s

Related question with more details.

like image 44
Pablo EM Avatar answered Oct 23 '22 11:10

Pablo EM