Skip to main content

exec form vs shell form PT.2

shell form

The PID 1 is the shell, which will spawn the process that the program it is actually running.

Any environment variable referenced will be resolved to it's actual value.

ENTRYPOINT ./run.sh "$PATH"

If the shell script run.sh just echos out the parameter that it is passed in, then it will output the actual path variable.

Using shell form with exec form

If you have the above ENTRYPOINT in shell form and wanted to add exec form for CMD like below

ENTRYPOINT ./run.sh
CMD ["$PATH"]

This will NOT expand the environment variable, in fact it will NOT even print "$PATH". This is because shell form used in Dockerfile puts all the arguments in one big string.

So what's going on?

So in the previous example, ENTRYPOINT ./run.sh "$PATH" results in running the command below in the terminal

/bin/sh -c "./run.sh $PATH"

Since it is executed as part of the shell program, the environment variable will get expanded and passed into the shell script.

However, with the second example it actually results in running below in the terminal

/bin/sh -c "./run.sh" "$PATH"

The way the shell program works if you pass in the -c flag is that only the first parameter will be recognize as the program and the parameter you want to execute. Any parameter after it are just simply IGNORED! Which means $PATH isn't even passed into the shell script!

exec form

Exec form takes the form of array of strings separated by commas. The way how it works is that it uses the exec command underneath and it simply replaces the current running process with the one you have specified. In this case, any command running in exec form will have PID of 1.

And because it is simply replacement of running process, there is no shell involved, and thus there are not shell variable expansion.

Running:

ENTRYPOINT ["./run.sh", "$PATH"]

will just print out $PATH LITERALLY, because shell isn't involved to do any expansions.

Combining with CMD in shell form

If you combine it with CMD in shell form it will just print out /bin/sh -c with any parameters that you have included

Combining with CMD in exec form

If you combine it with CMD in exec form then it will just include any additional parameter you have specified, WITHOUT shell expansion.