I like to check whether several packages are installed or not on Debian/Ubuntu Here is my attempt at a script to do this:

query=`dpkg-query -W -f '${Status}'`
ok="install ok"

if ! [ `$query`  curl == "$ok" ] ;then 
apt-get -y -qq install curl >> /dev/null 2>&1

The result is

Install: target Installed is not a directory 

but it should be what you can see in the second variable. I have a headache, npw because I can't find out the right way to handle this.

  • I strongly recommend to use long parameter names in scripts, that is apt-get --assume-yes --quiet=2
    – Fabian
    Jan 24 '15 at 15:33
  • @Fabian Any reason for the recommendation? Jan 24 '15 at 15:35
  • 1
    Why bother checking? Simply install. At worst you get an upgrade. Especially in the case of curl, it's easier to check for the existence if the curl binary itself.
    – muru
    Jan 24 '15 at 15:36
  • 1
    Sure: 1. it improves readability for those not knowing every short argument. That reduces the probability to misunderstand a command. 2. This (slightly) reduces the probability that different versions of the command will interpret an argument differently (unlikely for dpkg and apt, but happens a lot for e.g. ping). If you use a long argument you will get an error message instead of the program doing somethign else.
    – Fabian
    Jan 24 '15 at 15:38
  • 1
    Main problem: output of dpkg-query is install ok installed not install ok. Second: query should be function altogether with check and return exit code but not variable.
    – Costas
    Jan 24 '15 at 15:41

You seem to be doing things in a needlessly complicated way. Why not just

dpkg -l curl || apt-get -y -qq install curl > /dev/null 2>&1

You did ask for a one-liner after all. Since, presumably, all you want is to know whether curl is available, you could also just do

type curl >/dev/null 2>&1 || apt-get -y -qq install curl

There are two bugs in your code, one serious the other not so much:

  1. You are using backticks twice. Also don't use backticks. Use command substitution as the following: $(command ...)

    query=$(dpkg-query -W -f '${Status}')

    Query will already contain the result of the command call. When you now execute


    you will now try to execute the result, which is in your case a string, for me thats a very long string consisting of install ok installedinstall ok installed...

  2. (Costas pointed this out) The result of dpkg-query -W -f '${Status}' curl will be install ok installed, which is not what you check for.


There's no point to checking if a package is installed and installing if not. Either:

  1. You check for what you want from the package, like the curl binary: command -v curl, so that the user can provide alternatives if they feel like it.
  2. You check if a particular version of what you wanted is installed, using something like apt-cache policy.

If neither case applies, then it is simpler to install it directly.

  • well isnt it possible to say when query retuns installed install ok do nothing else run the apt-get command?
    – Josh
    Jan 24 '15 at 15:52
  • @Josh And what benefit does that offer over determining whether what you want is present? If the user cared to provide their own curl, for example, then what's the point of you installing it? You should be checking if what you want is provided or not, not whether the package is installed or not. Especially if your argument is "its faster".
    – muru
    Jan 24 '15 at 15:55
  • There's a reason to check first: that doesn't require root. So you can write something like dpkg -l curl || sudo apt-get install curl, and not prompt the user for a password if it isn't needed. Jan 24 '15 at 23:48
  • @Gilles how is that better than checking for the existence of the command or required version of the package?
    – muru
    Jan 24 '15 at 23:51
  • @muru It's not better than these, but it's better than straight up trying to install. Jan 24 '15 at 23:58

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.