I am trying to pass extra parameters from a container to the contained application. The following bash script is working to pass extra variables, but I'm not sure that it's optimal, or a standard method for running a containerized application. Any insight would be appreciated.
#!/bin/bash
# allow arguments to be passed to dnsmasq
if [[ ${1:0:1} = '-' ]]; then
EXTRA_ARGS="$@"
set --
elif [[ ${1} == dnsmasq || ${1} == $(which dnsmasq) ]]; then
EXTRA_ARGS="${@:2}"
set --
fi
# default behaviour is to launch dnsmasq
if [[ -z ${1} ]]; then
echo "Starting dnsmasq..."
exec $(which dnsmasq) --log-facility=- --keep-in-foreground --no-resolv --no-hosts --strict-order ${EXTRA_ARGS}
else
exec "$@"
fi
1 Answer 1
Shell variables should be lower-case, to avoid collision with environment variables that may be passed through.
We're making assumptions that $EXTRA_ARGS
will word-split back into the same constituents it was composed from.
Instead of using a plain string variable there, use an array:
extra_args=("$@")
extra_args=("${@:2}")
Then expand it as an array:
exec dnsmasq --log-facility=- --keep-in-foreground \
--no-resolv --no-hosts --strict-order \
"${extra_args[@]}"
(I took out the pointless which
, since that just uses the same path that exec
will use for lookup - unless there's a shell alias, in which case we could throw command
in there.)
Alternatively, we could just use the One True Array that portable shell supports, and remove the Bash extensions completely:
#!/bin/sh
set -eu
case "${1-}"
in
-*|'')
set -- dnsmasq "$@"
esac
# In Bash or ksh, we could use ;&, but plain POSIX shell doesn't
# support fallthrough, so we need a separate 'case' here.
case "${1}"
in
dnsmasq|*/dnsmasq)
shift
echo "Starting dnsmasq..."
exec dnsmasq --log-facility=- --keep-in-foreground \
--no-resolv --no-hosts --strict-order \
"$@"
esac
# Some other program specified
exec "$@"
Using #!/bin/sh
likely has lower overheads than starting the much larger Bash interpreter.