Scripts often start with defaults, then let configuration data override only the values that should change.

Program

Play the script to set a selectable default timeout and build the effective value.

timeout
config_defaults.sh
Replay: real traced execution (multi-file project)
#!/usr/bin/env bash

timeout=5
config_timeout=""
effective_timeout=${config_timeout:-$timeout}
echo "timeout=$effective_timeout"
#!/usr/bin/env bash

timeout=3
config_timeout=""
effective_timeout=${config_timeout:-$timeout}
echo "timeout=$effective_timeout"
#!/usr/bin/env bash

timeout=8
config_timeout=""
effective_timeout=${config_timeout:-$timeout}
echo "timeout=$effective_timeout"
  1. timeout ← 5

    3timeout=54config_timeout=""
    values this step5timeout
  2. config_timeout ← (empty)

    3timeout=54config_timeout=""5effective_timeout=${config_timeout:-$timeout}
    values this step(empty)config_timeout
  3. effective_timeout ← 5

    4config_timeout=""5effective_timeout=${config_timeout:-$timeout}6echo "timeout=$effective_timeout"
    values this step5effective_timeout(empty)config_timeout5timeout
  4. echo "timeout=$effective_timeout"

    5effective_timeout=${config_timeout:-$timeout}6echo "timeout=$effective_timeout"
    outputtimeout=5
    values this step5effective_timeout
  1. timeout ← 3

    3timeout=34config_timeout=""
    values this step3timeout
  2. config_timeout ← (empty)

    3timeout=34config_timeout=""5effective_timeout=${config_timeout:-$timeout}
    values this step(empty)config_timeout
  3. effective_timeout ← 3

    4config_timeout=""5effective_timeout=${config_timeout:-$timeout}6echo "timeout=$effective_timeout"
    values this step3effective_timeout(empty)config_timeout3timeout
  4. echo "timeout=$effective_timeout"

    5effective_timeout=${config_timeout:-$timeout}6echo "timeout=$effective_timeout"
    outputtimeout=3
    values this step3effective_timeout
  1. timeout ← 8

    3timeout=84config_timeout=""
    values this step8timeout
  2. config_timeout ← (empty)

    3timeout=84config_timeout=""5effective_timeout=${config_timeout:-$timeout}
    values this step(empty)config_timeout
  3. effective_timeout ← 8

    4config_timeout=""5effective_timeout=${config_timeout:-$timeout}6echo "timeout=$effective_timeout"
    values this step8effective_timeout(empty)config_timeout8timeout
  4. echo "timeout=$effective_timeout"

    5effective_timeout=${config_timeout:-$timeout}6echo "timeout=$effective_timeout"
    outputtimeout=8
    values this step8effective_timeout

Follow the Default

  1. timeout starts at 5.
  2. config_timeout is empty.
  3. ${config_timeout:-$timeout} uses timeout because the config value is empty.
  4. effective_timeout becomes 5.
  5. The script prints timeout=5. | timeout | config_timeout | effective_timeout | output | | ---: | --- | ---: | --- | | 3 | empty | 3 | timeout=3 | | 5 | empty | 5 | timeout=5 | | 8 | empty | 8 | timeout=8 |
default A script default gives the program a value even when config is absent.
:- `${name:-fallback}` expands to the fallback when `name` is empty or unset.
effective value The effective value is the one later commands should use.

Exercise: config_defaults.sh

Reproduce timeout=5, then use the pinned timeout values 3 and 8 to predict timeout=3 and timeout=8.