Home > Software engineering >  bash, key-value pair to determine the package manager in use
bash, key-value pair to determine the package manager in use

Time:09-30

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
  • Related