1

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
fi

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.

Faheem Mitha
  • 35,108
Josh
  • 135
  • 1
  • 9
  • 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? – DisplayName 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
  • because there is an iso that does the job before the script I like to using this code in is running but the script should work without the iso, too. Why should Install them again or in other words run pt-get again when checking is very much faster. – Josh Jan 24 '15 at 15:38
  • I think what you really want to know is: How can I install missing packages without the overhead of just apt-get install a b c? Or do you really care whether they were installed before? – Fabian Jan 24 '15 at 15:41
  • 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
  • apt-cache policy pkgname1 pkgname2 will show you whether your packages are installed, if so what versions are installed,and what other versions are available, if any, in a compact format. It works for me. – Faheem Mitha Jan 24 '15 at 16:31

3 Answers3

3

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
terdon
  • 242,166
2

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

    `$query`
    

    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.

Fabian
  • 1,095
0

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.

muru
  • 72,889
  • 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. – Gilles 'SO- stop being evil' 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. – Gilles 'SO- stop being evil' Jan 24 '15 at 23:58