source runs shell assignment lines in the current shell, so later commands can use the loaded variables.

Program

Play the script to load a selected profile name and use the sourced settings.

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

profile="dev"
source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")
label="${profile}:${host}:${retries}"
echo "$label"
#!/usr/bin/env bash

profile="test"
source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")
label="${profile}:${host}:${retries}"
echo "$label"
#!/usr/bin/env bash

profile="prod"
source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")
label="${profile}:${host}:${retries}"
echo "$label"
  1. profile ← dev

    3profile="dev"4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")
    values this stepdevprofile
  2. host ← dev.local, retries ← 2

    3profile="dev"4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")5label="${profile}:${host}:${retries}"
    values this stepdev.localhost2retriesdevprofile
  3. label ← dev:dev.local:2

    4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")5label="${profile}:${host}:${retries}"6echo "$label"
    values this stepdev:dev.local:2labeldevprofiledev.localhost2retries
  4. echo "$label"

    5label="${profile}:${host}:${retries}"6echo "$label"
    outputdev:dev.local:2
    values this stepdev:dev.local:2label
  1. profile ← test

    3profile="test"4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")
    values this steptestprofile
  2. host ← test.local, retries ← 2

    3profile="test"4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")5label="${profile}:${host}:${retries}"
    values this steptest.localhost2retriestestprofile
  3. label ← test:test.local:2

    4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")5label="${profile}:${host}:${retries}"6echo "$label"
    values this steptest:test.local:2labeltestprofiletest.localhost2retries
  4. echo "$label"

    5label="${profile}:${host}:${retries}"6echo "$label"
    outputtest:test.local:2
    values this steptest:test.local:2label
  1. profile ← prod

    3profile="prod"4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")
    values this stepprodprofile
  2. host ← prod.local, retries ← 2

    3profile="prod"4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")5label="${profile}:${host}:${retries}"
    values this stepprod.localhost2retriesprodprofile
  3. label ← prod:prod.local:2

    4source <(printf "host=%s\nretries=%s\n" "${profile}.local" "2")5label="${profile}:${host}:${retries}"6echo "$label"
    values this stepprod:prod.local:2labelprodprofileprod.localhost2retries
  4. echo "$label"

    5label="${profile}:${host}:${retries}"6echo "$label"
    outputprod:prod.local:2
    values this stepprod:prod.local:2label

Follow the Source

  1. profile starts as dev.
  2. printf builds assignment lines for host=dev.local and retries=2.
  3. source loads those assignments into the current shell.
  4. label joins profile, host, and retries.
  5. The script prints dev:dev.local:2. | profile | sourced host | sourced retries | output | | --- | --- | ---: | --- | | dev | dev.local | 2 | dev:dev.local:2 | | test | test.local | 2 | test:test.local:2 | | prod | prod.local | 2 | prod:prod.local:2 |
source `source file` evaluates assignment lines in the current shell.
current shell Variables loaded by `source` remain available to following commands.
profile A profile name can choose which settings are loaded.

Exercise: source_config_stream.sh

Reproduce dev:dev.local:2, then use profiles test and prod to predict test:test.local:2 and prod:prod.local:2.