10

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 Answer 1

23

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.
4
  • 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? Commented Feb 10, 2023 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. Commented Feb 10, 2023 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
    Commented Feb 12, 2023 at 12:15
  • @stevea Not cryptic, it just requires you to actually read it :-)
    – Kusalananda
    Commented Jul 23 at 14:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .