There is a way to declare (-n
) a variable in Bash as a reference to another variable (kind of pointer). This allows us to pass multiple arrays to functions or create utility functions like:
# Check if variable is set. Will return true even when the value is an empty string.
# Usage: is_set VAR_NAME
is_set () {
declare -n __var="$1"
[[ "${__var+set}" = 'set' ]]
}
or
# Translate characters in a string
# Usage: translate STR FROM_CHARS TO_CHARS
translate () {
declare str="$1"
declare -n __from="$2"
declare -n __to="$3"
declare i
[[ "${#__from[@]}" = "${#__to[@]}" ]] || return 1
for i in "${!__from[@]}"; do
str="${str//"${__from[$i]}"/"${__to[$i]}"}"
done
printf '%s\n' "$str"
}
$ declare -a from=(a b)
$ declare -a to=(c d)
$ translate "abc" from to
cdc
or
pushopts () {
declare -n __opts="$1"
readarray -t __opts < <(shopt -po)
}
popopts () {
declare -n __opts="$1"
declare cmd
for cmd in "${__opts[@]}"; do
eval "$cmd"
done
}
$ set -e
$ pushopts BACKUP
$ set +e
$ popopts BACKUP
$ shopt -po errexit
set -o errexit