Search code examples
bashshelldockerdocker-composedocker-command

Dereference environment variable on parameter expansion in shell script


I am trying to dereference the value of environment variable using parameter expansion $@, but it doesn't seem to work.

I need to call a shell script with certain arguments. The list of arguments contain environment variables, and the environment variables are expected to be present where the shell script is to be executed. I do not know the list of commands before hand, so I am expanding those list of commands using $@. However, the script is not able to de-reference the value of environment variables.

A minimal setup which explains my problem can be done as below.

  • Dockerfile
FROM alpine:3.10

ENV MY_VAR=production

WORKDIR /app

COPY run.sh .

ENTRYPOINT [ "sh", "run.sh" ]
  • run.sh
#!/bin/sh

echo "Value of MY_VAR is" $MY_VAR

echo "Begin"

$@

echo "Done"

I can build the image using docker build . -t env-test. When I run it using docker run env-test:latest 'echo $MY_VAR', I get the below output.

Value of MY_VAR is production
Begin
$MY_VAR
Done

While the output that I am expecting is:

Value of MY_VAR is production
Begin
production
Done

SideNote: In actuality I am trying to run it using a compose file like below:

version: '3'

services:
  run:
    image: env-test:latest
    command: echo $$MY_VAR

but it again gives me the similar result.


Solution

  • Expanding on the eval approach, here is a simple bash script that will use eval to evaluate a string as a sequence of bash commands:

    #!/usr/bin/env bash
    echo program args:  $@
    eval $@
    

    but beware, eval comes with dangers:

    https://medium.com/dot-debug/the-perils-of-bash-eval-cc5f9e309cae