home | list info | list archive | date index | thread index

Re: [OCLUG-Tech] some weird shell parameter substitution constructs

On 2018-04-08 04:21 AM, Robert P. J. Day wrote:
>   not sure if i'm reading a shell script properly ... here's a script
> for downloading and installing kubernetes:
> 
>   https://get.kubernetes.io/
> 
> but it seems to be doing strange (messy) things with parameter
> substitution.
> 
>   first, there's this bit of weirdness partway through the script:
> 
>     if [[ -x ./cluster/get-kube-binaries.sh ]]; then
>       # Make sure to use the same download URL in get-kube-binaries.sh
>       KUBERNETES_RELEASE_URL="${KUBERNETES_RELEASE_URL}" \
>         ./cluster/get-kube-binaries.sh
>     fi
> 
>   i'm unsure of the value of assigning a variable to itself; is there
> something subtle or tricky about that assignment that isn't obvious?

If the variable $KUBERNETES_RELEASE_URL is local (ie. not exported to the global environment using the export
statement), this construct will export it to the environment of the subcommand, which it otherwise wouldn't do.  The
author may not want it set in the environment of other subcommands.  Controlling unintended  side effects is a hallmark
of good developer hygiene.

>   then there are a number of constructs like this:
> 
>     if [[ -n "${KUBERNETES_SKIP_CREATE_CLUSTER-}" ]]; then
>       exit 0
>     fi
> 
>   AIUI, the whole point of the construct ${VAR-default}
> 
> is if VAR is not set, then the value of "default" will be used. so
> what does it mean to say:
> 
>     ${VAR-}
> 
> that is, to have the empty string as the default value? is this some
> magic that i am unaware of?

That construct tests the value of $KUBERNETES_SKIP_CREATE_CLUSTER for an empty or unset value without side effects.
Sometimes you don't want side effects, like setting an environment variable that was not already set if all you want to
do is test it.

>   and there's this near the top:
> 
> KUBERNETES_RELEASE_URL="${KUBERNETES_RELEASE_URL:-https://dl.k8s.io}";
> 
> ok, that will admittedly set that variable to a value if it does not
> already have a value, but i've always done that this way:
> 
>   : ${VAR:=defaultvalue}

What would happen if I ran the script with, say, VAR="&& rm -rf /" ?  Consider that installer scripts are often meant to
be run as root.

> the script clearly works, but it seems to have been written by someone
> who didn't quite grasp proper parameter substitution. thoughts?

I'm more concerned that some dev at Kubernetes is trying to write a portable script using bash-specific constructs like
'[['.  They ought to be flayed alive and forced to repent.


-- 
Stephen M. Webb  <stephen [ dot ] webb [ at ] bregmasoft [ dot ] ca>