9

I've come across this piece of code from here:

#!/bin/bash

...

if [[ "${1-}" =~ ^-*h(elp)?$ ]]; then echo "Usage..." exit fi

I understand what this does is print the usage information when any argument like -h, --help, -help, -------help is passed.

But why "${1-}" and not just "${1}"? What does the hyphen do?

At first I thought it could mean any argument from the position 1 onward. I tried it and no, it wasn't that.

Then I thought it could be a typo and the author meant "${1-9}" to allow all number positions. Again, it didn't work, it isn't even valid code.

1 Answers1

22

A hyphen in a parameter expansion allows a default value to be specified. So ${1-} means “the value of the first parameter if it is set, and the empty string otherwise”.

That doesn’t seem particularly useful as-is, because an unset variable expands to the empty string anyway. However, ${1} will cause an error if set -u is enabled and no parameter is given, whereas ${1-} won’t — so some shell programmers always use this form when referring to variables which may legitimately be unset.

In the context of the site you found this on, this fits in with “thing” number 5:

  1. Prefer to use set -o nounset. You may have a good excuse to not do this, but, my opinion, it’s best to always set it.

    • This will make the script fail, when accessing an unset variable. Saves from horrible unintended consequences, with typos in variable names.
    • When you want to access a variable that may or may not have been set, use "${VARNAME-}" instead of "$VARNAME", and you’re good.
Stephen Kitt
  • 434,908
  • 1
    In that question you have linked they mention a lot "${a:-b}" (with :-) instead of just "${a-b}". I've tried finding the meaning in the answers but couldn't. Does it make a big difference? – xtropicalsoothing Feb 10 '23 at 10:23
  • 5
    In this case it doesn’t. ${a:-b} expands to b if a is either unset or empty, ${a-b} expands to b if a is unset. Since the default in ${1-} is empty, ${1-} and ${1:-} have the same effect. – Stephen Kitt Feb 10 '23 at 10:35
  • The bash man page wrt "Parameter expansion" is rather cryptic, it states "Omitting the colon results in a test only for a parameter that is unset". – stevea Feb 12 '23 at 12:15