What is the meaning of a question mark in bash variable parameter expansion as in ${var?}?

17,979

Solution 1

It works almost the same as (from the bash manpage):

${parameter:?word}
Display Error if Null or Unset. If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted.

That particular variant checks to ensure the variable exists (is both defined and not null). If so, it uses it. If not, it outputs the error message specified by word (or a suitable one if there is no word) and terminates the script.

The actual difference between that and the non-colon version can be found in the bash manpage above the section quoted:

When not performing substring expansion, using the forms documented below, bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset.

In other words, the section above can be modified to read (basically taking out the "null" bits):

${parameter?word}
Display Error if Unset. If parameter is unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted.

The difference is illustrated thus:

pax> unset xyzzy ; export plugh=

pax> echo ${xyzzy:?no}
bash: xyzzy: no

pax> echo ${plugh:?no}
bash: plugh: no

pax> echo ${xyzzy?no}
bash: xyzzy: no

pax> echo ${plugh?no}

pax> _

There, you can see that while both unset and null variable result in an error with :?, only the unset one errors with ?.

Solution 2

It means that the script should abort if the variable isn't defined

Example:

#!/bin/bash
echo We will see this
${Server?Oh no! server is undefined!}
echo Should not get here

This script will print out the first echo, and the "Oh no! ..." error message.

See all the variable substitutions for bash here: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

Solution 3

As per man bash:

  • ${parameter:?word}

If parameter is null or unset, the expansion of word (or a message to that effect if word is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of parameter is substituted.

So if you omit word and don't pass $1 to your function or shell script then it will exit with this error:

-bash: 1: parameter null or not set

However you can place a user-defined error to let your caller know that a required argument has not been set e.g.:

local arg1="${1:?needs an argument}"

It will continue running script/function only if $1 is set.

Solution 4

:? causes the (non-interactive) shell to exit with an error message if given parameter is null or unset. The script you are looking at is omitting the error message; usually, you'd see something like

foo=${1:?Missing first argument}

For example,

$ foo=${1:?Missing first argument}
bash: 1: Missing first argument
$ set firstarg
$ foo=${1:?Missing first argument}
$ echo $foo
firstarg
Share:
17,979
Kai
Author by

Kai

Working as a Java Developer currently.

Updated on June 06, 2022

Comments

  • Kai
    Kai almost 2 years

    What is the meaning of a bash variable used like this:

     ${Server?}