declare -n создаёт ссылку на другую переменную — псевдоним по имени:

declare -n ref=target
target="hello"
echo "$ref"   # hello
ref="world"
echo "$target" # world

Главная польза — возврат значений из функций без глобальных переменных и eval:

get_ip() {
    declare -n _out=$1
    _out=$(hostname -I | awk '{print $1}')
}

get_ip MY_IP
echo "$MY_IP"

Косвенное раскрытие ${!var} — более старый способ, работает без declare -n:

varname="PATH"
echo "${!varname}"  # значение $PATH

# динамические переменные в цикле
for env in DEV STAGE PROD; do
    key="DB_HOST_${env}"
    echo "$env${!key}"
done

declare -n требует bash 4.3+. На macOS встроен bash 3.2 — там только ${!var}.

#linux #bash #sysadmin