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

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

  • Subject: Re: [OCLUG-Tech] some weird shell parameter substitution constructs
  • From: "Robert P. J. Day" <rpjday [ at ] crashcourse [ dot ] ca>
  • Date: Sun, 8 Apr 2018 08:41:35 -0400 (EDT)
On Sun, 8 Apr 2018, Stephen M. Webb wrote:

> 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.

  yes, that occurred to me about 10 minutes after i posted. le *sigh*.

> >   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.

  that one you're going to have to explain in more detail. i've seen a
lot of scripts in my day, and i've *never* seen that construct. i'm
not sure what "side effects" you're referring to here.

> >   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.

  i'm going to test this to see if that's actually what would happen.
>
> > 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.

  agreed.

rday