How to make a package manager wait if another instance of APT is running?

Solution 1:

You can make apt-get to learn to wait if another software manager is running. Something similar with the behaviour from the next screen cast:

enter image description here

How I made it?

I create a new script called apt-get (wrapper for apt-get) in /usr/local/sbin directory with the following bash code inside:

#!/bin/bash

i=0
tput sc
while fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do
    case $(($i % 4)) in
        0 ) j="-" ;;
        1 ) j="\\" ;;
        2 ) j="|" ;;
        3 ) j="/" ;;
    esac
    tput rc
    echo -en "\r[$j] Waiting for other software managers to finish..." 
    sleep 0.5
    ((i=i+1))
done 

/usr/bin/apt-get "$@"

Don't forget to make it executable:

sudo chmod +x /usr/local/sbin/apt-get

Before to test, check if everything is ok. The output of which apt-get command should be now /usr/local/sbin/apt-get. The reason is: by default, the /usr/local/sbin directory is placed before /usr/bin directory in user or root PATH.

Solution 2:

You can use the aptdcon command Manpage icon to queue up package manager tasks by communicating with aptdaemon instead of using apt-get directly.

So basically you can just do sudo aptdcon --install chromium-browser or whatever and while that command is running you can run it again but install different packages and apt-daemon will just queue them up instead of erroring out.

This is especially useful if you're doing a long upgrade or something and want to keep installing packages or if you're scripting something together and want to make sure installing things will be more reliable.

Solution 3:

A very simple approach would be a script that waited for the lock to not be open. Let's call it waitforapt and stick it in /usr/local/bin:

#!/bin/sh

while sudo fuser /var/{lib/{dpkg,apt/lists},cache/apt/archives}/lock >/dev/null 2>&1; do
   sleep 1
done

Then just run sudo waitforapt && sudo apt-get install whatever. You could add exceptions into sudoers to allow you to run it without needing a password (you'll need it for the apt-get so it's no great gain).

Unfortunately this doesn't queue things. Given that some of apt's operations are interactive ("Are you sure you want to remove all those packages?!"), I can't see a good way around this...