0
#!/bin/bash if [[ $(which yum) ]]; then OS="CentOS" elif [[ $(which apt) ]]; then OS="Debian" elif [[ $(which apk) ]]; then OS="Alpine" elif [[ $(which zypper) ]]; then OS="OpenSuse" elif [[ $(which pacman) ]]; then OS="Arch" elif [[ $(which dnf) ]]; then OS="Fedora" else IS_UNKNOWN=1 fi echo "$IS_UNKNOWN" suse="OpenSuse" alpine2="Alpine" cent="CentOS" redhat="Fedora" deb="Debian" pacman="Arch" if (( OS==suse )) then export package_manager="zypper install -y" elif (( OS==alpine2 )) then export package_manager="apk --update add" elif (( OS==cent )) then export package_manager="yum install -y" elif (( OS==redhat )) then export package_manager="dnf install -y" elif (( OS==pacman )) then export package_manager="pacman -Sy" elif (( OS==deb )) then export package_manager="apt install -y" else printf "No package manager detected, aborting." exit 1 fi echo "$package_manager" 

Trying to detect the package manager of a linux user in bash , but it always seems to output zypper even when the package manager I'm using is not zypper and zypper is not installed.Anyone know what could be causing the problem?

4
  • The logic of your code is strange. You detect the an available package manager to figure out the OS, to figure out the package manager. Couldn't you just skip the middle step there and just do command -v zypper >/dev/null 2>&1 && pkg_mgr=zypper etc.?
    – Kusalananda
    CommentedDec 10, 2021 at 22:37
  • I didn't add the installation commands for the package manager before, now it should make more sense.CommentedDec 10, 2021 at 23:09
  • 1
    Note that most Linux distros these days have a file called /etc/os-release which can be used to identify the distro. e.g. [ -f /etc/os-release ] && OS="$(awk -F= '{/^ID=/ {print $2}')". Or, since the file contains shell-compatible variable assignments, you can just source the file and use the variables defined in it ($ID contains the distro short name that you're after).
    – cas
    CommentedDec 11, 2021 at 4:53
  • It's cheating a bit, but if you assume ansible is available, installing a package, e.g. zsh, could be done on virtually any system with ansible -bK -m ansible.builtin.package -a 'name=zsh state=present' localhost.
    – Kusalananda
    CommentedDec 11, 2021 at 7:40

1 Answer 1

4

In bash, ((...)) is strictly for arithmetic expressions. The words OS and alpine are taken as variable names, and as those variables don't contain numbers, they are given the value zero. 0==0 is true, so zypper.

What you want is the builtin [[...]] construct for string comparisons.

if [[ "$OS" == "zypper" ]] 

Take note that [[ (as well as [ and test) do different things based on how many arguments they get, which means it's really important to put spaces around the operator.

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.