An Introduction to Parameter Expansion in Bash | Hacker Noon

Author profile picture

@wesleydavidWesley David

Site Reliability Engineer who sometimes fixes what he breaks.

I came across a lesser-used Bash idiom while attempting to implement ZeroSSL TLS certificates. Specifically, in ZeroSSL’s wrapper script to install their implementation of certbot. The idiom is seen here:


My interest was piqued by that one little dash in between




To understand it, I’ll pull back and think about the whole line, component by component.


Let’s look at this line as if it was two sides of a seesaw with the middle being the


sign. The left half


is simply a variable assignment. Whatever the right side of the


expands to is going to be put inside the variable



So far, so simple.

${ }

On the right side of the


, we have a dollar sign and a bunch of stuff within a pair of braces. Let’s ignore the content within the braces for now and examine the use of


as our next element.

The dollar sign character is interpreted by Bash to introduce a number of possible things, including command substitution, arithmetic evaluation, accessing the value of a named variable, or a parameter expansion.

Command substitution is triggered in Bash with


and ends with a closing


. You could fill a variable with the return value of any command like this:

MY_VARIABLE=$( command )

Arithmetic substitution is triggered in bash with


and ends with a matching


. Whatever is between the double parentheses is expanded and treated as an arithmetic expression.

Variable values are accessed when a


is followed by a named variable. You’ve already seen one named variable in this article:



However, it currently has no value. In fact, as you read this, we’re currently in the midst of figuring out what value is going to be assigned to that variable.

Parameter expansion is introduced into bash with


and ending with a corresponding


. Any shell parameter found within the braces is expanded. There are a lot of arcane and esoteric shell parameters, but you’ve already been introduced to one type of shell parameter in this article: a variable. That’s right, shell variables are parameters. This brings us to the final piece of this puzzle.


We know that


is a variable and thus a shell parameter, so Bash will attempt to expand it within the


construct. However, we’re pretty sure that it’s empty at this point. And what’s with the double-quoted string that contains a URL? And why is a dash separating them?! That lowly dash is the linchpin that holds all of this together.

Within a parameter expansion expression, the dash will test if the variable on the left is set or not. If it is set, the variable is expanded and what’s on the right is discarded.

However, if the parameter on the left of the dash is not set, then the thing on the right side of the dash is expanded (if it needs to be) and then assigned as the value of the variable on the left of the dash. Let’s take a look at our specimen:


The above says, in plain language: “Does the variable


exist? If it does, return the variable’s value.

If the variable doesn’t exist, then insert the string


into it, and finally return that value.

Putting it all Together

Whew! We’ve been through a lot, but there’s still a bit more to go. Let’s take a look at the whole line again, explain what’s happening, and then put it in context:


We’re creating a variable named


and assigning it the final value of the parameter expansion on the right side of the



Within that parameter expansion expression, we’re checking if


already exists. If it does, return the value of that variable which is immediately assigned to that exact same variable. This looks a little weird, but it’s a Bash idiom that means “If


already exists, leave it alone.”

However, if the variable


does not exist, then create it and put the string



To put things into greater context, that variable is later used within a call to




The question you may now be asking is: “Why?!” Why not avoid the use of a seldom used, single character test that took so long to explain? Why not use curl and supply the URL directly? Without asking the script author, here are three reasons that I think the script was written this way:

Abstraction. We use variables for any information that has a reasonable chance of being changed. A URL can easily change, and if we assign it to a variable once, we can more easily change that value at a later date. We never need to worry about changing the URL in every spot that we used it.

Documentation. When you assign a value to a variable, you name the variable. In this case, our value is a URL. What exactly does that URL do? What is its purpose? When we assign the URL to a variable named


, now we have an explanation. Every time we use that variable it reminds us of what it’s doing.

Safety. The two reasons above explain the use of variables, but not that lone dash. I believe the dash idiom was chosen for safety. Maybe we ran the script multiple times before, or perhaps something else set it previously. We don’t need to keep repeating the process of setting the variable, and if it was set previously, let’s not overwrite it.

Final Thoughts

I noticed that the script does not check


for a value that makes sense. What if it’s set, but has a number in it? Or a string that isn’t an HTTP URL? Those are more complex problems. How would you solve them?

In the title of this article, I used a slightly different bash idiom: the use of


rather than the lonesome


. If we look to Bash’s documentation, we find:

When not performing substring expansion, using the form described below (e.g., ‘:-’), Bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset.

The dash merely checks for the existence of the variable on its left. The colon-dash will additionally check if the variable exists but is null. If the value is null, then Bash assigns the value on the right to the variable. Ask yourself which logic makes the most sense for your own scripts.

Do you have any scripts you’d like me to tear down? Any shell idioms that you’re not sure about? Comment below!

Previously published at

Author profile picture

Read my stories

Site Reliability Engineer who sometimes fixes what he breaks.


Join Hacker Noon

Create your free account to unlock your custom reading experience.

read original article here