I want to write a bash script allowing me to check, whether a certain package is already installed in arch linux.
How can I do that?
I want to write a bash script allowing me to check, whether a certain package is already installed in arch linux.
How can I do that?
You should use Pacman, the package manager of Arch Linux.
You want to use the -Q
operation to query the installed local package database and the -i
option to get information on the package.
This gives you
pacman -Qi <packageName>
You can then use the exit code to determine if the packages existes on the system or not (0 the package exists, 1 it doesn't)
The usage of -i
rather than -s
ensures you will check for exactly that package and not for the presence of a a package containing the package name in its name.
For example if I search for chromium
(the web browser) on a system where only chromium-bsu
(the game) is installed,
# This exits with 1 because chromium is not installed
pacman -Qi chromium
# This exits with 0 because chromium-bsu is installed
pacman -Qs chromium
As Random Citizen pointed out, you certainly want to redirect any output to /dev/null
if you are writing a script and don't want Pacman to pollute your output:
pacman -Qi <packageName> > /dev/null
You can use the arch package management tool pacman.
As you can see in the Arch-Wiki, the -Qs
option can be used to search within the installed packages.
If the package exists, pacman -Qs
will exit with the exit-code 0, otherwise with the exit-code 1
You script might look like:
package=firefox
if pacman -Qs $package > /dev/null ; then
echo "The package $package is installed"
else
echo "The package $package is not installed"
fi
The > /dev/null
pipe is used to suppress the printed output.
I usually just do ls /bin | grep $package
(replacing $package with the package I'm looking for). It's quick for the computer too.
It depends on the name of the package though, because this will list all of the installed executables that have $package in their name. Nevertheless, if you have executables installed with $package in their name, there's a big chance the package you're looking for is already installed.
Here is a more accurate one:
package="lshw";
check="$(sudo pacman -Qs --color always "${package}" | grep "local" | grep "${package} ")";
if [ -n "${check}" ] ; then
echo "${package} is installed";
elif [ -z "${check}" ] ; then
echo "${package} is NOT installed";
fi;
Even better, how about turning it into a function?
There's 2 examples in the code below. You can use _install
to install just one package. You can use _installMany
to install as many packages as you want. I included both functions because _installMany
is kind of complex, and looking at the slightly simpler _install
function might help someone understand it.
#!/bin/bash
_isInstalled() {
package="$1";
check="$(sudo pacman -Qs --color always "${package}" | grep "local" | grep "${package} ")";
if [ -n "${check}" ] ; then
echo 0; #'0' means 'true' in Bash
return; #true
fi;
echo 1; #'1' means 'false' in Bash
return; #false
}
# `_install <pkg>`
_install() {
package="$1";
# If the package IS installed:
if [[ $(_isInstalled "${package}") == 0 ]]; then
echo "${package} is already installed.";
return;
fi;
# If the package is NOT installed:
if [[ $(_isInstalled "${package}") == 1 ]]; then
sudo pacman -S "${package}";
fi;
}
# `_installMany <pkg1> <pkg2> ...`
# Works the same as `_install` above,
# but you can pass more than one package to this one.
_installMany() {
# The packages that are not installed will be added to this array.
toInstall=();
for pkg; do
# If the package IS installed, skip it.
if [[ $(_isInstalled "${pkg}") == 0 ]]; then
echo "${pkg} is already installed.";
continue;
fi;
#Otherwise, add it to the list of packages to install.
toInstall+=("${pkg}");
done;
# If no packages were added to the "${toInstall[@]}" array,
# don't do anything and stop this function.
if [[ "${toInstall[@]}" == "" ]] ; then
echo "All packages are already installed.";
return;
fi;
# Otherwise, install all the packages that have been added to the "${toInstall[@]}" array.
printf "Packages not installed:\n%s\n" "${toInstall[@]}";
sudo pacman -S "${toInstall[@]}";
}
package="lshw";
_install "${package}";
packages=("lshw" "inkscape");
_installMany "${packages[@]}";
#Or,
_installMany "lshw" "inkscape"
Try this:
isPackageInstalled() {
pacman -Qi "$packageName" &> /dev/null
echo $?
}
Using in a script is as simple as
if [ $(isPackageInstalled 'libssl') ]; then
# do things here
echo 'Package libssl is installed'
fi
Personnaly, I use the following :
Append this to your ~/.bashrc
, then source it:
havei() {
package=$1
if $(pacman -Qi $package &>/dev/null); then
echo -e "\e[92m[ ] $package is installed \e[39m"
else
echo -e "\e[91m[ ❌ ] $package is not installed \e[39m"
fi
}
Then you can simply use it in your everydays terminal:
havei firefox
pacman -Q pkgName
if package is not installed, you will receive an error message:
error: pacmage 'pkgName' was not found
If package is installed, then a single line is printed:
pkgName x.y.z-r
pacman -Qi pkgName
behaves the same way, only it prints detailed information about existing package.