This is the same situation as a question I asked about a year ago, however I am now targeting RHEL7 and Bash 4.2.46.
I am writing scripts to install packages from archive files, checking if the package is already installed first. I have the information for each package file in a config file like so:
declare -A package_a=([name]="utility-blah" [ver]="2.4.1")
declare -A package_b=([name]="tool-bleh" [ver]="1.3.9")
# and so on and so forth
My various install scripts source this config file to get package information. Each script contains an array of the packages to be installed. I would like to iterate over this array and install the package named. Ideally, the meat of this loop is in some function so I don’t have to rewrite it in each script. In Ubuntu 18 with Bash 4.4, I was able to include this function in the config file like so:
function install_package()
{
# dereference hashmap variable
declare -n package="$1"
if dpkg --list ${package[name]}; then
echo "${package[name]} is installed"
else
dpkg -i $pathToPackages/${package[name]}_${package[ver]}.deb
fi
}
This leaves only the loop for the actual script, which looks like this:
source packages.config
source functions.config
declare -a packageList=("package_a" "package_b" "package_d")
for package in ${packageList[@]}; do
install_package $package
done
This worked perfectly for me on Bash 4.4. Unfortunately, the declare -n
option was added in Bash 4.3, and as I am now targeting Bash 4.2, the nameref solution no longer works. Is there a way I can have this same behavior where the script will dereference the package
variable? I’ve tried using indirection as this post suggests, but I don’t think ${!package[name]}
works the way I want it to.
Is it possible to achieve the same functionality without using declare -n
?
2
Answers
Add the index to your indirection variable:
This works on Bash 4.2.45(1)
Can this achieve what you expected ?