Frage Wie man einen Paketmanager wartet, wenn eine andere Instanz von APT läuft?


Ich habe viele Software wie Update Manager und Synaptic Package Manager gesehen, sie warten, wenn ein anderes Programm den /var/lib/dpkg/lock und ist gesperrt. Wie können wir das durch das Terminal machen? ich sah apt-getHandbuch, fand aber nichts Nützliches.


45
2018-05-05 13:09


Ursprung


Nun, Sie können mehrere apt-get-Befehle ausführen. Mögen sudo apt-get install packagename && sudo apt-get update und sie werden automatisch nach einander passieren. - Alvar
Tut dies nicht: sudo apt-get install packagename1 packagename2 packagename3  ? - Rinzwind


Antworten:


Sie können verwenden das aptdcon Befehl Manpage icon Aufgaben des Paketmanagers durch die Kommunikation mit aptdaemon anordnen, anstatt apt-get direkt zu verwenden.

Also im Grunde können Sie einfach tun sudo aptdcon --install chromium-browser oder was auch immer und während dieser Befehl ausgeführt wird, können Sie ihn erneut ausführen, aber verschiedene Pakete installieren, und apt-daemon wird sie nur in die Warteschlange stellen, anstatt einen Fehler zu melden.

Dies ist besonders nützlich, wenn Sie ein langes Upgrade oder etwas durchführen und weiterhin Pakete installieren möchten oder wenn Sie etwas gemeinsam erstellen und sicherstellen möchten, dass die Installation zuverlässiger ist.


31
2017-12-22 20:55



Kann aptdcon so ausgeführt werden, dass es beliebige Ansagen als akzeptiert apt-get -y tut das? - Noki
yes | aptdcon --hide-terminal --install "package" Hide Terminal wird benötigt, sonst Piping yes wird Probleme verursachen. - whitehat101
Das Problem mit dieser Antwort ist, dass es installiert werden muss aptdcon. Ich arbeite an einem Bootstrap-Skript, das die Ersteinrichtung eines VPS durchführt, wo ein Hintergrundprozess auch einige initiale Einstellungen vornimmt. Ich kann nicht installieren aptdcon bis ich das Schloss umgehen kann. - Fake Name
@FakeName für die initiale Serverkonfiguration möchten Sie wahrscheinlich cloud-init verwenden: cloudinit.readthedocs.io/en/latest - Jorge Castro
welches Paket ist aptdcon im? - ctrl-alt-delor


Du kannst das schaffen apt-get zu warten, wenn ein anderer Software-Manager läuft. Ähnliches gilt für das Verhalten vom nächsten Screencast:

enter image description here

Wie ich es gemacht habe?

Ich erstelle ein neues Skript namens apt-get (Wrapper für apt-get) im /usr/local/sbin Verzeichnis mit dem folgenden Bash-Code innerhalb:

#!/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 "$@"

Vergiss nicht, es ausführbar zu machen:

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

Überprüfen Sie vor dem Test, ob alles in Ordnung ist. Die Ausgabe von which apt-get Befehl sollte jetzt sein /usr/local/sbin/apt-get. Der Grund ist: standardmäßig /usr/local/sbin Verzeichnis wird vorher platziert /usr/bin Verzeichnis in Benutzer oder Root PATH.


40
2017-11-10 16:27



Das ist wirklich ein direkter Schlag auf meine Frage. Vielen Dank :) - Ten-Coin
Wie verwaltet Ihr Skript gestapelte Instanzen von apt-get? Wie, bevor es fertig ist, starte ich 5 weitere apt-get? - Braiam
@Braiam Mit freundlichen Grüßen, ich weiß es nicht; Ich bin kein guter Tester. Hast du es getestet? Wenn Probleme auftreten, kann das Skript verbessert werden, indem eine neue Sperre mit Zeitstempel erstellt wird, wenn eine neue Instanz des Skripts gestartet wird (nur ein Beispiel - es gibt auch viele andere Möglichkeiten). - Radu Rădeanu
Beeindruckend! beredt. wirkt wie ein Zauber mit allem, was ich bisher darauf geworfen habe! Zwei Daumen hoch ... das sollte nur ein Teil des Pakets sein: D - Eric
Das ist perfekt! Ich hatte ein Problem, wo ich AWS cloudinit verwende, um Pakete auf einem neuen Server zu installieren, aber Ubuntu tut einiges apt Sachen auf dem Boot, so mein dpkg Der Befehl ist aufgrund der gesperrten dpkg db fehlgeschlagen. Ich habe diesen One-Liner in meine Cloudinit-Benutzerdaten eingefügt: while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 1; done; dpkg -i package.deb und es funktioniert großartig. - Volodymyr Smotesko


Abgesehen vom Offensichtlichen &&, suchst du vielleicht aptdcon. Dieses Tool kann andere Instanzen von apt erkennen und auf das Ende warten:

sudo aptdcon --safe-upgrade
[/] 11% Warten auf andere Software-Manager zu beenden Auf Eignung warten

(Ich leite Eignung woanders)

Der Vorteil dieses Tools besteht darin, dass Sie mehrere Aktionen nacheinander ablegen können, ohne sich darum sorgen zu müssen, was Sie als nächstes tun werden. aptdcon ist ideal für unbeaufsichtigte Skripte und GUI-Installation, da Sie das Tool im Hintergrund laufen lassen können, um Ihr Frontend nicht zu blockieren.

Die Operationen, die von unterstützt werden aptdcon sind:

  • --refresh, -c: Dies ist das Äquivalent zu apt-get update. Es aktualisiert Ihre Paketliste.
  • --install, --remove, --upgrade, --purge, --downgrade. Jeder von ihnen tut, was seine Namen sagen. Der Name der Pakete ist obligatorisch. -i, -r, -u, -p: Dies sind die kurzen Optionen für alle außer Downgrade, die keine hat.
  • --safe-upgrade, --full-upgrade sind die Gegenstücke zu apt-getist es upgrade/dist-upgrade und aptitudeist es safe-upgrade/full-upgrade. Diese benötigen keine Parameter.
  • Es gibt einige andere Operationen, die im Handbuch zu finden sind. Aber diese werden am meisten von Benutzern verwendet, die daran interessiert sind aptd. Es gibt Optionen, die sich mit denen überschneiden apt-key, apt-cache, dpkg machen.

apt-get selbst unterstützt solche Methoden nicht (um auf andere Instanzen von apt zu warten), also aptdcon ist die bevorzugte Lösung für die Paketmanager von GUI: USC verwendet aptd als Back-End, wie Synaptic. Andere Lösung ist packagekit, aber es unterstützt (noch) nicht die Funktion, nach der Sie suchen.


20
2017-11-09 12:19



aptdcon --install /path/to/pgk.deb Funktioniert wie dpkg -i, obwohl ich dies im Handbuch nicht explizit finden konnte. - whitehat101
Kann ich das im Nachinstallations-Skript in einem Paket verwenden? - Nelson Teixeira
@NelsonTeixeira Warum würdest du das im ppst-install Skript benutzen? Wenn die Installation nach der Installation ausgeführt wird, läuft offensichtlich apt. - Braiam
Ich möchte nach der Installation einige spezielle Pakete installieren, die nicht im Repository sind. Ist das möglich ? Ich würde sie im Paket einschließen und dann würde das Skript sie nach der Installation installieren. - Nelson Teixeira
@NelsonTeixeira nochmal, wieso wäre das nötig? Die Nachinstallations-Skripts werden nur bei einer Paketinstallation ausgeführt. Ich schlage vor, Sie zu Stellen Sie stattdessen eine Frage und erkläre deinen Fall detaillierter. - Braiam


Ein sehr einfacher Ansatz wäre ein Skript, das darauf wartet, dass das Schloss nicht geöffnet wird. Nennen wir es waitforapt und kleben Sie es ein /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

Dann lauf einfach sudo waitforapt && sudo apt-get install whatever. Sie könnten Ausnahmen hinzufügen sudoers damit Sie es ausführen können, ohne ein Passwort zu benötigen (Sie benötigen es für die apt-get also ist es kein großer Gewinn).

Leider stehen die Dinge nicht in der Warteschlange. Da einige Operationen von apt interaktiv sind ("Sind Sie sicher, dass Sie alle diese Pakete entfernen möchten ?!"), sehe ich keinen guten Weg in dieser Richtung ...


16
2017-11-09 12:50



könnte sein -y Ja für alle Operationen annehmen? - Braiam
Vielen Dank. Ich denke, ich kann es besser verwenden, wenn ich Alias-Hilfe verwende. - Ten-Coin
In nicht sicher -y ist aber wünschenswert. - Oli♦
Ich glaube nicht, dass du dich einwickeln willst sudo fuser im [[ $(...) ]]. Es gibt einen Null-Exit-Code zurück, wenn auf die Datei zugegriffen wird, was ausreichend sein sollte. - kiri
Ich habe die folgende Lösung gefunden, um vollständiger zu sein, da bei der Arbeit mit apt-get mehrere Sperren beteiligt sind: while sudo fuser /var/lib/dpkg/lock /var/lib/apt/lists/lock /var/cache/apt/archives/lock >/dev/null 2>&1; do echo 'Waiting for release of dpkg/apt locks'; sleep 5; done; sudo apt-get -yy update - Manuel Kiessling


Sie könnten eine Abfragetechnik verwenden:

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

3
2017-12-09 22:29



besser zu benutzen inotify - ctrl-alt-delor


Ich habe ein Skript gemacht, das das tut:

#!/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

Speichern Sie das obige in /usr/local/sbin/apt-get. apt-get wartet dann, wenn bereits eine andere Instanz läuft.

Alternativ speichern Sie es als /usr/local/sbin/apt-wait, Beispiel Verwendung:

apt-wait && aptitude

was wird laufen aptitude Nach dem aktuellen Prozess wurde das Schloss verlassen.

Beispiellauf:

  1. Erstens, ein apt-get Befehl wird ausgeführt, zum Beispiel:

    $ sudo apt-get remove some_package
    
  2. Dann wird in einem anderen Terminal ein anderer Befehl ausgeführt:

    $ sudo apt-get install some_other_package
    

    Es wird gewartet, bis der erste Befehl beendet und ausgeführt wird. Ausgabe während des Wartens:

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

3
2018-01-19 04:32



besser zu benutzen inotify - ctrl-alt-delor


Leider macht fuser nicht viel für Sie, wenn Sie in verschiedenen nicht privilegierten Namespacebehältern wie lxc laufen.

Außerdem wird aptdcon nicht standardmäßig (mindestens am 18.04) installiert und Hintergründe Ihrer Aufgabe in einer Warteschlange, so dass Sie die Serialisierung verlieren. Dies ist nicht unüberwindbar, aber es bedeutet, dass Ihre Automatisierung eine Möglichkeit haben muss, Flockfehler in apt bei der Installation von aptdcon zu vermeiden, und Sie müssen Warteschleifen für alles haben, was Sie nach der Installation von Paketen über aptdcon serialisieren müssen es sei denn, es gibt bereits eine Art Flagge dafür.

Was ist Arbeit? Dies sollte auch über NFS usw. funktionieren, da es die Dateisystemsperrung auf die gleiche Weise wie apt verwendet, nur mit dem Parameter -w Sekunden wird auf Ihre Sperre gewartet, anstatt einen Fehler auszulösen.

Folgt also dem Wrapper-Modell, fügt dies als apt-get in / usr / local / bin / hinzu und teilt es mit.

Dies hat auch den Vorteil, IO zu begrenzen, indem keine Parallelität auf apt zugelassen wird, so dass Cron Updates um Mitternacht überall auslösen kann, ohne die Festplatte zu verprügeln.

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

Eine sehr nette und einfache Feature-Anforderung für apt-get wäre ein -w-Flag, um zu einer blockierenden / wartenden Sperre zu wechseln.


2
2017-09-07 18:02





One-Liner basiert auf Olis Antwort:

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

0
2018-02-27 06:55