I want to detect the package manager on the system and then use that later on in my script. However, I feel this is clunky.
type apt &> /dev/null && MANAGER=apt && DISTRO="Debian/Ubuntu"
type yum &> /dev/null && MANAGER=yum && DISTRO="RHEL/Fedora/CentOS"
type dnf &> /dev/null && MANAGER=dnf && DISTRO="RHEL/Fedora/CentOS" # $MANAGER=dnf will be default if both dnf and yum are present
type zypper &> /dev/null && MANAGER=zypper && DISTRO="SLES"
type apk &> /dev/null && MANAGER=apk && DISTRO="Alpine"
What I would like to do is define some kind of array or key-value pair such that
apt, Debian/Ubuntu
dnf, RedHat/Fedora/CentOS
and then have a function that allocates based on this pseudo-code:
for each item in the key-value pair {
type {key} &> /dev/null && MANAGER={key} && DISTRO={value}
}
Can someone show me how that might be constructed in bash?
CodePudding user response:
Just define text. Of space separated columns, with newline separated elements.
list=$(cat <<EOF
apt Debian/Ubuntu
dnf RedHat/Fedora/CentOS
EOF
)
while IFS=' ' read -r key value; do
if type "$key"; then...
done <<<"$list"
Prefer to use if
instead of &&
for readability. You could use a different separator, to store spaces in elements, preprocess the list if you want to put some comments.
You could also use multiple arrays:
keys=(apt dnf)
managers=(Debian/Ubuntu RedHat/Fedora/CentOS)
for ((i=0;i<${#keys}; j)); do
if type "${keys[i]}"; then
You could also use associative arrays:
declare -A managers=(
[apt]=Debian/Ubuntu
[dnf]=RedHat/Fedora/CentOS
)
for key in "${!managers[@]}"; do
manager=${managers["$key"]}
done
Prefer to use lower case variables in scripts. Check your scripts with shellcheck.
CodePudding user response:
Defining such an array isn't going to be significantly less clunky than what you already have.
declare -A managers
managers[apt]="Debian/Ubuntu"
managers[yum]="RHEL/Fedora/CentOS"
# etc
for k in "${!managers[@]}"; do
if type "$k"; then
MANAGER=$k
DISTRO=${managers[$k]}
break
fi
done