Assigning default values to shell variables with a single command in bash

BashShell

Bash Problem Overview


I have a whole bunch of tests on variables in a bash (3.00) shell script where if the variable is not set, then it assigns a default, e.g.:

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi

I seem to recall there's some syntax to doing this in one line, something resembling a ternary operator, e.g.:

FOO=${ ${VARIABLE} : 'default' }

(though I know that won't work...)

Am I crazy, or does something like that exist?

Bash Solutions


Solution 1 - Bash

Very close to what you posted, actually. You can use something called Bash parameter expansion to accomplish this.

To get the assigned value, or default if it's missing:

FOO="${VARIABLE:-default}"  # If variable not set or null, use default.
# If VARIABLE was unset or null, it still is after this (no assignment done).

Or to assign default to VARIABLE at the same time:

FOO="${VARIABLE:=default}"  # If variable not set or null, set it to default.

Solution 2 - Bash

For command line arguments:

VARIABLE="${1:-$DEFAULTVALUE}"

which assigns to VARIABLE the value of the 1st argument passed to the script or the value of DEFAULTVALUE if no such argument was passed. Quoting prevents globbing and word splitting.

Solution 3 - Bash

If the variable is same, then

: "${VARIABLE:=DEFAULT_VALUE}"

assigns DEFAULT_VALUE to VARIABLE if not defined. The double quotes prevent globbing and word splitting.

Also see Section 3.5.3, Shell Parameter Expansion, in the Bash manual.

Solution 4 - Bash

To answer your question and on all variable substitutions

echo "${var}"
echo "Substitute the value of var."
 	

echo "${var:-word}"
echo "If var is null or unset, word is substituted for var. The value of var does not change."
 	

echo "${var:=word}"
echo "If var is null or unset, var is set to the value of word."
 	

echo "${var:?message}"
echo "If var is null or unset, message is printed to standard error. This checks that variables are set correctly."
 	

echo "${var:+word}"
echo "If var is set, word is substituted for var. The value of var does not change."

You can escape the whole expression by putting a \ between the dollar sign and the rest of the expression.

echo "$\{var}"

Solution 5 - Bash

Even you can use like default value the value of another variable

having a file defvalue.sh

#!/bin/bash
variable1=$1
variable2=${2:-$variable1}

echo $variable1
echo $variable2

run ./defvalue.sh first-value second-value output

first-value
second-value

and run ./defvalue.sh first-value output

first-value
first-value

Solution 6 - Bash

see here under 3.5.3(shell parameter expansion)

so in your case

${VARIABLE:-default}

Solution 7 - Bash

FWIW, you can provide an error message like so:

USERNAME=${1:?"Specify a username"}

This displays a message like this and exits with code 1:

./myscript.sh
./myscript.sh: line 2: 1: Specify a username

A more complete example of everything:

#!/bin/bash
ACTION=${1:?"Specify 'action' as argv[1]"}
DIRNAME=${2:-$PWD}
OUTPUT_DIR=${3:-${HOMEDIR:-"/tmp"}}

echo "$ACTION"
echo "$DIRNAME"
echo "$OUTPUT_DIR"

Output:

$ ./script.sh foo
foo
/path/to/pwd
/tmp

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION takes the value of the first argument, and exits if empty
  • $DIRNAME is the 2nd argument, and defaults to the current directory
  • $OUTPUT_DIR is the 3rd argument, or $HOMEDIR (if defined), else, /tmp. This works on OS X, but I'm not positive that it's portable.

Solution 8 - Bash

Then there's the way of expressing your 'if' construct more tersely:

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}

Solution 9 - Bash

Here is an example

#!/bin/bash

default='default_value'
value=${1:-$default}

echo "value: [$value]"

save this as script.sh and make it executable. run it without params

./script.sh
> value: [default_value]

run it with param

./script.sh my_value
> value: [my_value]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEdward Q. BridgesView Question on Stackoverflow
Solution 1 - BashAndrew McGregorView Answer on Stackoverflow
Solution 2 - BashmikuView Answer on Stackoverflow
Solution 3 - BashHans GinzelView Answer on Stackoverflow
Solution 4 - BashGuruView Answer on Stackoverflow
Solution 5 - BashMontellsView Answer on Stackoverflow
Solution 6 - Bashghostdog74View Answer on Stackoverflow
Solution 7 - BashCurtis MattoonView Answer on Stackoverflow
Solution 8 - BashRob WellsView Answer on Stackoverflow
Solution 9 - BashAssaf ShomerView Answer on Stackoverflow