How to check if a virtual package is installed?
In the following question there is a solution to checking for a package prior to installing it:
How do I check if a package is installed on my server?
However, I have found that this does not work for Virtual Packages.
Is there a way to traverse the package name that apt-get automatically select and check for the correct one?
Apt will not install a virtual package unless there is only one provider for it. If another package depends on a virtual package, it usually also names a real package as an alternative (i.e. build-essential depend on "libc6-dev | libc-dev" - the second being a virtual package).
Virtual packages are not installed, thus you cannot check their status. You can use apt-cache showpkg <pkg-name>
to view which packages provide the virtual package, and then check whether any of these are installed.
You can use grep-status (package dctrl-tools
, not installed by default) to find all installed packages providing some virtual package:
$ grep-status -FProvides,Package -sPackage,Provides,Status awk
Package: mawk
Provides: awk
Status: install ok installed
Package: gawk
Provides: awk
Status: install ok installed
@FlorianDiesch'answer looks interesting, but I want something without need for any software not installed by default.
I ended up using this:
function check_packages_and_install_if_absent()
{
for PACKAGENAME
do
if
dpkg -l "$PACKAGENAME" | grep ^ii
then
echo "Package $PACKAGENAME is present"
continue
fi
FOUND=""
while read ACTUALPACKAGENAME
do
echo "$PACKAGENAME is a virtual package, that can be provided by $ACTUALPACKAGENAME"
if
dpkg -l "$ACTUALPACKAGENAME" | grep ^ii
then
echo "Actual package $ACTUALPACKAGENAME is present"
FOUND=true
break;
fi
done < <( apt-cache showpkg "${PACKAGENAME}" | sed -e '1,/^Reverse Provides: *$/ d' -e 's/ .*$//' | sort | uniq )
# Using sed to print lines after match
# https://stackoverflow.com/questions/32569032/sed-print-all-lines-after-match#answer-32569573
if [[ "$FOUND" == "true" ]]
then
continue
fi
echo "Package $PACKAGENAME is absent, installing"
sudo apt-get install -y "$PACKAGENAME"
done
}
You can call it with a list of normal and/or virtual package names:
function check_packages_and_install_if_absent foo bar baz