Is there a way (from a script) to identify the default system package manager?
To clarify, what I want to do is run a given command and, on Debian or any of its derivatives it’ll return something like “apt”, on openSUSE it’ll return “zypp”, on Fedora et al it’ll return “yum”, on Arch Linux it’ll return “pacman” etc.
I know I can do this with something like the following, I just wondered if there was a more robust method that won’t break as soon as there is an executable with the same name.
which apt >/dev/null 2>&1
if [ $? -eq 0 ]
then
echo "apt"
fi
# etc...
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Instead of identify binary programs, you should start from identify distributions,
Just give you few lines that works in bash scripting:
declare -A osInfo;
osInfo[/etc/redhat-release]=yum
osInfo[/etc/arch-release]=pacman
osInfo[/etc/gentoo-release]=emerge
osInfo[/etc/SuSE-release]=zypp
osInfo[/etc/debian_version]=apt-get
osInfo[/etc/alpine-release]=apk
for f in ${!osInfo[@]}
do
if [[ -f $f ]];then
echo Package manager: ${osInfo[$f]}
fi
done
Althrough these parts can’t be trusted, but generally people won’t do that.
Method 2
Start with the accepted answer to this question: How can I get distribution name and version number in a simple shell script?. Then, decide which package manager you want to use based on the detected distribution.
Method 3
I opted to go this route after reviewing the others. This came up for me when running many docker containers and needing curl / jq and not being able to rely on what was available from job to job.
script: - packagesNeeded='curl jq' - if [ -x "$(command -v apk)" ]; then sudo apk add --no-cache $packagesNeeded - elif [ -x "$(command -v apt-get)" ]; then sudo apt-get install $packagesNeeded - elif [ -x "$(command -v dnf)" ]; then sudo dnf install $packagesNeeded - elif [ -x "$(command -v zypper)" ]; then sudo zypper install $packagesNeeded - else echo "FAILED TO INSTALL PACKAGE: Package manager not found. You must manually install: $packagesNeeded">&2; fi
In pure bash:
packagesNeeded='curl jq'
if [ -x "$(command -v apk)" ]; then sudo apk add --no-cache $packagesNeeded
elif [ -x "$(command -v apt-get)" ]; then sudo apt-get install $packagesNeeded
elif [ -x "$(command -v dnf)" ]; then sudo dnf install $packagesNeeded
elif [ -x "$(command -v zypper)" ]; then sudo zypper install $packagesNeeded
else echo "FAILED TO INSTALL PACKAGE: Package manager not found. You must manually install: $packagesNeeded">&2; fi
Method 4
I am using this function to provide dependencies. I am defining package manager and their how to use.
check_dependencies(){
#Declare list of dependencies
declare -Ag deps=([docker]='docker.io' [wg]='wireguard-tools' [lsof]='lsof')
#Declare list of package managers and their usages
declare -Ag packman_list=([pacman]='pacman -Sy' [apt]='echo "deb http://deb.debian.org/debian buster-backports main contrib non-free" > /etc/apt/sources.list.d/buster-backports.list; apt update -y; apt install -y' [yum]='yum install -y epel-release; yum repolist -y; yum install -y')
#Find the package manager on the system and install the package
install_deps(){
for packman in ${!packman_list[@]}
do
which $packman &>/dev/null && eval $(echo ${packman_list[$packman]} "$*")
done
}
#Find the missing packages from list of dependencies
declare -ag missing_deps=()
for pack in ${!deps[@]}
do
which $pack &>/dev/null || missing_deps+=(${deps[$pack]})
done
#Install missing dependencies
test -z ${missing_deps[0]} || install_deps ${missing_deps[@]} || fail "Dependencies could not provide"
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0