Test if a package is installed in APT
I want a shell script method to test/report if a package is installed. I don't need details, only boolean return to set logic flow. I looked at Find if a package is installed, but dpkg
returns complex output and its format changes depending on whether the package is in the Debian repository or in an Ubuntu PPA.
I found that apt-cache
does a pretty good job and I came up with this method:
is_installed=0
test_installed=( `apt-cache policy package-name | grep "Installed:" ` )
[ ! "${test_installed[1]}" == "(none)" ] && is_installed=1
Does anyone know a simpler or more direct way?
dpkg-query
as in your linked post seems to be the most correct tool for the job, except using e.g. the available Python libraries to bind directly to the APT system in such a scripting context.
With dpkg-query
:
dpkg-query -Wf'${db:Status-abbrev}' package-name 2>/dev/null | grep -q '^i'
Will return true (exit status 0
in shell script) if the package is installed, false (exit status 1
) otherwise.
-
-W
means "Show" (dpkg-query
must have a requested action). -
-f
changes the format of the output. -
db:Status-abbrev
is the short form of the package status. -
2>/dev/null
silencesdpkg-query
if an invalid package name is given. How this should be handled could be a case-to-case issue. -
grep -q
returns true if there is a match, false otherwise.
If it is used often, it could be made a simple function:
#!/bin/sh
debInst() {
dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
}
if debInst "$1"; then
printf 'Why yes, the package %s _is_ installed!\n' "$1"
else
printf 'I regret to inform you that the package %s is not currently installed.\n' "$1"
fi
or just simply
#!/bin/sh
if dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'; then
printf 'Why yes, the package "%s" _is_ installed!\n' "$1"
else
printf 'I regret to inform you that the package "%s" is not currently installed.\n' "$1"
fi
I tested Daniel's suggestions on three packages with these results:
-
Native Debian repository package not installed:
~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl ~$ echo $? 1
-
PPA package registered on host and installed:
~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice ~$ echo $? 0
-
PPA package registered on host but not installed:
~$ dpkg-query -Wf'${db:Status-abbrev}' domy-ce ~$ echo $? 0 ~$ sudo apt-get remove domy-ce [sudo] password for user: Reading package lists... Done Building dependency tree Reading state information... Done Package domy-ce is not installed, so not removed 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Although I like the approach, it seems I can't trust the return code with PPA packages. Short of that, I think I'll stick with parsing the return of the apt-cache policy
command.