64 votes

Comment faire attendre un gestionnaire de paquets si une autre instance d'APT est en cours d'exécution ?

J'ai vu de nombreux logiciels tels que Update Manager et Synaptic Package Manager, qui attendent qu'un autre programme utilise l'adresse IP. /var/lib/dpkg/lock et est verrouillé. Comment pouvons-nous faire cela par le biais du terminal ? J'ai vu apt-get mais je n'ai rien trouvé d'utile.

4voto

Malheureusement, Fuser ne fait pas grand-chose pour vous lorsque vous vous exécutez dans différents conteneurs d'espaces de noms non privilégiés comme lxc.

De plus, aptdcon n'est pas installé par défaut (au moins sur 18.04) et place votre tâche dans une file d'attente, ce qui vous fait perdre la sérialisation. Ce n'est pas insurmontable, mais cela signifie que votre automatisation doit avoir un moyen d'éviter les erreurs de flocage dans apt lors de l'installation d'aptdcon, et vous devrez avoir une sorte de boucle d'attente pour tout ce que vous devez sérialiser après l'installation de paquets via aptdcon, à moins qu'il y ait déjà une sorte d'indicateur pour cela.

Ce qui fonctionne, c'est le flocage. Cela devrait également fonctionner sur NFS, etc. car il utilise le verrouillage du système de fichiers de la même manière qu'apt, mais avec le paramètre -w seconds, il attendra votre verrouillage au lieu de lancer une erreur.

En suivant le modèle du wrapper, ajoutez ceci comme apt-get dans /usr/local/bin/ et partagez.

Cela présente également l'avantage de limiter les entrées-sorties en n'autorisant pas le parallélisme sur apt, de sorte que vous pouvez laisser cron déclencher des mises à jour à minuit partout sans solliciter le disque.

#!/bin/bash
exec /usr/bin/flock -w 900 -F --verbose /var/cache/apt/archives/lock /usr/bin/apt-get $@  

Une très belle et simple demande de fonctionnalité pour apt-get serait un drapeau -w pour passer à un verrouillage bloquant / d'attente.

3voto

malthe Points 131

Vous pourriez utiliser une technique de sondage :

$ time (while ps -opid= -C apt-get > /dev/null; do sleep 1; done); \
  apt-get -y install some-other-package

3voto

kiri Points 25860

J'ai créé un script qui fait cela :

#!/bin/bash

# File path to watch
LOCK_FILE='/var/lib/dpkg/lock'

# tput escape codes
cr="$(tput cr)"
clr_end="$(tput el)"
up_line="$(tput cuu 1)"

CLEAN(){
    # Cleans the last two lines of terminal output,
    # returns the cursor to the start of the first line
    # and exits with the specified value if not False

    echo -n "$cr$clr_end"
    echo
    echo -n "$cr$clr_end$up_line"
    if [[ ! "$1" == "False" ]]; then
        exit $1
    fi
}

_get_cmdline(){
    # Takes the LOCKED variable, expected to be output from `lsof`,
    # then gets the PID and command line from `/proc/$pid/cmdline`.
    #
    # It sets `$open_program` to a user friendly string of the above.

    pid="${LOCKED#p}"
    pid=`echo $pid | sed 's/[\n\r ].*//'`
    cmdline=()
    while IFS= read -d '' -r arg; do
        cmdline+=("$arg")
    done < "/proc/${pid}/cmdline"
    open_program="$pid : ${cmdline[@]}"
}

# Default starting value
i=0

# Checks if the file is locked, writing output to $FUSER
while LOCKED="$(lsof -F p "$LOCK_FILE" 2>/dev/null)" ; do
    # This will be true if it isn't the first run
    if [[ "$i" != 0 ]]; then
        case $(($i % 4)) in
            0 ) s='-'
                i=4
                _get_cmdline # Re-checks the command line each 4th iteration
            ;;
            1 ) s=\\ ;;
            2 ) s='|' ;;
            3 ) s='/' ;;
        esac
    else
        # Traps to clean up the printed text and cursor position
        trap "CLEAN False; trap - SIGINT ; kill -SIGINT $$" SIGINT
        trap 'CLEAN $((128+15))' SIGTERM
        trap 'CLEAN $((128+1))' SIGHUP
        trap 'CLEAN $((128+3))' SIGQUIT

        # Default starting character
        s='-'

        _get_cmdline
        echo -n "$save_cur"
    fi
    # Prints the 2nd line first so the cursor is at the end of the 1st line (looks nicer)
    echo
    echo -n "$cr$clr_end$open_program"
    echo -n "$up_line$res_cur$cr$clr_end[$s] Waiting for other package managers to finish..."
    #echo -en "$cr$clr_end[$s] Waiting for other package managers to finish..."
    #echo -en "\n$cr$clr_end$open_program$cr$up_line"
    ((i++))
    sleep 0.025
done

CLEAN False

# This allows saving the script under a different name (e.g. `apt-wait`)
# and running it. It only imitates `apt-get` if it was launched as such
if [[ "${0##*/}" == 'apt-get' ]]; then
    exec /usr/bin/apt-get "$@"
    exit $?
fi

Sauvegarder ce qui précède dans /usr/local/sbin/apt-get . apt-get attendra ensuite si une autre instance est déjà en cours d'exécution.

Vous pouvez également l'enregistrer sous le nom de /usr/local/sbin/apt-wait exemple d'utilisation :

apt-wait && aptitude

qui exécutera aptitude après que le processus actuel détenant le verrou soit sorti.

Exemple d'exécution :

  1. Premièrement, un apt-get est exécutée, par exemple :

    $ sudo apt-get remove some_package
  2. Ensuite, dans un autre terminal, une autre commande est exécutée :

    $ sudo apt-get install some_other_package

    Il attendra que la première commande soit terminée puis s'exécutera. Sortie pendant l'attente :

    [/] Waiting for other package managers to finish...
          28223 : /usr/bin/apt-get remove some_package

3voto

Mendhak Points 4198

Depuis la version 1.9.11 apt y apt-get ont une option qui vous permet d'attendre que les verrous de dpkg soient libérés.

Utilisez le DPkg::Lock::Timeout pour définir un délai d'attente, en secondes, pour une commande apt-get. Dans cet exemple, le délai d'attente est de 60 secondes :

sudo apt-get -o DPkg::Lock::Timeout=60 install packagename

Si vous fixez cette valeur à -1, il continuera à attendre indéfiniment.

sudo apt-get -o DPkg::Lock::Timeout=-1 install packagename

Pour plus d'informations, voir : Attendre les verrous d'apt sans les scripts de bash. . Cette option a été ajouté à apt-get en février 2020 .

1voto

szmoore Points 111

Selon que vous enveloppez ou non tous les accès à apt-get ou pas, cela peut fonctionner :

flock ./apt.lock apt-get install ...

Créez votre propre serrure avec flock(1) au lieu d'essayer d'intercepter les différentes dpkg serrures.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X