Bash Set If Unset

on

shell scripting, tested in Bash 5.0.16(1)-release (x86_64-pc-linux-gnu), on grml 2020.06

Psuedocode

if var a is not set
    then set var a to 1234

The purpose here is to assign a variable a default value only if a value wasn't already provided. Ie: caller of the script can choose to export their own variable, but if not the code will still run with a default value instead.

If Statement

The obvious way to do this is to implement the psuedocode in its long form. This way is readable but is overly verbose for the simple operation being performed.

# if variable a is zero-length, then assign it 1234
if [[ -z "$a" ]]; then
    a=1234;
fi
echo $?   #echo error-code
echo "$a"
0
1234

The square-bracket notation is really just syntactic sugar for the test command, it can also be accomplished by specifying test.

if test -z "$a"; then
    a=1234;
fi

Test Or Assign

This way is shorter without sacrificing readability (assuming some shell scripting experience). Notice it is 'n' instead of 'z' test this time

[ -n "$a" ] || a=1234;  # nonzero length or assign
echo $?
echo "$a"
0
1234

Using test directly works too:

test -n "$a" || a=1234;

The Advanced, Terse Way

There is a short way to accomplish this, by using a special shell expansion syntax := colon-equals. To prevent shell parameter expansion from trying to run the resulting string as a command a no-op colon operator is used as the first word of the shell line.

: "${a:=1234}"
echo $?
echo "$a"
0
1234

Here is a default passcode example, saved in a config script, to use 1234 as the passcode if it wasn't given a value yet.

passcode.cfg

: "${pass:=1234}"

Command Line

#!/bin/bash
chmod +x passcode.cfg

export pass=9999
. ./passcode.cfg
echo "$pass"

pass=  #unset pass
. ./passcode.cfg  # has to be done with . or source, so it will affect current shell (rather than a subshell)
echo "$pass"

Output

9999
1234