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:

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 silences dpkg-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:

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"
    printf 'I regret to inform you that the package %s is not currently installed.\n' "$1"

or just simply

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"
    printf 'I regret to inform you that the package "%s" is not currently installed.\n' "$1"
  • While this is doubtless correct I find that dpkg-query -l "$package" | grep -q ^.i is usually sufficient (and easier to remember). – phogg May 22 '12 at 10:54
  • 1
    @phogg: Yes, depends on whether it is supposed to live in a script or not. Also, the dpkg-query -l output is not set in stone since it is just a user presentation mode, so if the presentation changes perhaps such a script would break. – Daniel Andersson May 23 '12 at 10:30
  • @Daniel. I like the return code approach. Please see my answer with details in code. – tahoar May 23 '12 at 12:46
  • On 10.04 the format option db:Status-abbrev doesn't seem to exist -- I used: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*' to the same effect. – scottynomad Oct 11 '12 at 13:41

I tested Daniel's suggestions on three packages with these results:

  1. Native Debian repository package not installed:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
  2. PPA package registered on host and installed:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
  3. PPA package registered on host but not installed:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' domy-ce
    ~$ echo $?
    ~$ 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.

  • Well, your code examples are not what I said you should do, but I guess you have just missed the grep part in your pasting. I can't really reproduce your issue, but that might be because the code examples are currently incomplete, so please fix that. Do you run Debian or Ubuntu? – Daniel Andersson May 23 '12 at 13:18
  • I'm running Ubuntu 10.04 (are PPA's supported no straight Debian?). My code dropped the your grep because 1) the dkpg-query command writes nothing to stdout and grep always throws a returncode. The dpkg-query returncode is 0 if installed. – tahoar May 23 '12 at 14:29
  • 2
    1. Don't tag your post "Debian" then. 2. I don't think you understood the part grep played in the command, so you stripped it, and now you say it doesn't work? grep -q gives return code 1 if it doesn't match, i.e. the program is not installed or unavailable, or 0 if the program is installed. I explained that in my post. – Daniel Andersson May 24 '12 at 9:05

# Check for dependencies 
check_deps () {
DEPS=$(echo {dialog,sqlite3,openssh-client})
for i in $DEPS ; do
    dpkg-query -W -f='${Package}\n' | grep ^$i$ > /dev/null
    if [ $? != 0 ] ; then
        echo "Installing deps ..."
        aptitude install $i -y > /dev/null

# execute the check_deps function
  • -1, the question is not about dependency checking. Also, explain what the parts of the command is doing: otherwise other people can't see what's going on. – Daniel Andersson Feb 11 '13 at 16:55
  • DEPS=$(echo {dialog,sqlite3,openssh-client}) can be equivalently written as just DEPS="dialog sqlite3 openssh-client". – Daniel Andersson Feb 11 '13 at 16:56

I like Daniel Andersson's answer, but it didn't work for me. I'm on Ubuntu 12.04.

From the dpkg man page, db:Status-abbrev only works in dpkg 1.16.2+:

                 It  contains the abbreviated package status, such as “ii”
                 (since dpkg 1.16.2).

My solution was to use legacy behavior, just the Status formatter:

dpkg-query -Wf'${Status}' {my_pkg_name}


install ok installed 

I'm guessing this was the inspiration for "ii" in other representations.

So, to completely adapt Daniel Andersson's answer to work on older version of dpkg, and thus older Ubuntu distros:

dpkg-query -Wf'${Status}' {your_pkg_name} 2>/dev/null | grep -q "install ok installed"


  • 0 - package is installed, or
  • 1 - package is NOT installed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.