6

In a bash script I want to install a package. Before sanely doing so, I need to check if no other instance of apt-get or dpkg is already working. If that was the case, the apt-get would fail, because its already locked.

Is it sufficient to check if /var/lib/dpkg/lock and /var/lib/apt/lists/lock exists and if both don't exist, installing is safe?

jmizv
  • 1,172
  • 2
  • 11
  • 28
user28464
  • 173
  • 2
  • 12

4 Answers4

2

It depends how well you want to handle apt-get errors. For your needs checking /var/lib/dpkg/lock and /var/lib/apt/lists/lock is fine, but if you want to be extra cautious you could do a simulation and check the return code, like this:

if sudo apt-get --simulate install packageThatDoesntExist      
then echo "we're good"
else echo "oops, something happened"
fi

Which will give for instance:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package packageThatDoesntExist
oops, something happened

Edit: --simulate will not check for locks, so you might want to do an additional check there. You might also want to remove sudo, if you want to check for sudo separately.

jmizv
  • 1,172
  • 2
  • 11
  • 28
diogovk
  • 2,108
  • 2
  • 19
  • 24
2

In Debian Wheezy (currently stable), those files always exist. Therefore I found using lsof /var/lib/dpkg/lock to be a more useful check. It returns 1 if nothing is using the lock, 0 if it is, so:

lsof /var/lib/dpkg/lock >/dev/null 2>&1
[ $? = 0 ] && echo "dpkg lock in use"
Ryley
  • 21,046
  • 2
  • 67
  • 81
2

Checking lock files is insufficient and unreliable. Perhaps what you really want to do is to check whether dpkg database is locked. I do it using the following approach:

## check if DPKG database is locked
dpkg -i /dev/zero 2>/dev/null
if [ "$?" -eq 2 ]; then
    echo "E: dpkg database is locked."
fi

Hopefully there is a better way...
Besides I also do the following check as it might be unsafe to install if there are broken packages etc.:

apt-get check >/dev/null 2>&1
if [ "$?" -ne 0 ]; then
    echo "E: \`apt-get check\` failed, you may have broken packages. Aborting..."
fi
Onlyjob
  • 5,692
  • 2
  • 35
  • 35
  • Not sure why, but lsof and fuser were both failing for me on a virtualbox guest (neither was outputting anything and both returned 1 no matter what). This solution saved me. – kael Jan 28 '18 at 06:22
  • This is racy as it is susceptible to TOCTOU though. – Guillem Jover Aug 06 '21 at 22:37
2

You can simply check if apt-get or dpkg are running:

ps -C apt-get,dpkg >/dev/null && echo "installing software" || echo "all clear"
Guss
  • 30,470
  • 17
  • 104
  • 128
  • A potential downfall of this method is that there are many possible applications that can lock apt. As of Ubuntu 16.04 `apt` is the preferred command, which your test won't catch. Keeping up with possible front-ends could prove to be a headache. – David Baucum Mar 15 '17 at 19:20