Testen Sie, ob ein Paket in APT installiert ist


10

Ich möchte, dass eine Shell-Skriptmethode testet / meldet, wenn ein Paket installiert ist. Ich brauche keine Details, nur eine boolesche Rückgabe, um den Logikfluss festzulegen. Ich habe nach Suchen gesucht, ob ein Paket installiert ist , aber dpkgkomplexe Ausgaben zurückgibt und das Format ändert sich je nachdem, ob sich das Paket im Debian-Repository oder in einem Ubuntu-PPA befindet.

Ich fand, dass apt-cachedas einen ziemlich guten Job macht und habe mir diese Methode ausgedacht:

is_installed=0
test_installed=( `apt-cache policy package-name | grep "Installed:" ` )
[ ! "${test_installed[1]}" == "(none)" ] && is_installed=1

Kennt jemand einen einfacheren oder direkteren Weg?

Antworten:


12

dpkg-query wie in Ihrem verlinkten Beitrag scheint das korrekteste Werkzeug für den Job zu sein, außer dass Sie beispielsweise die verfügbaren Python-Bibliotheken verwenden, um in einem solchen Skriptkontext direkt an das APT-System zu binden.

Mit dpkg-query:

dpkg-query -Wf'${db:Status-abbrev}' package-name 2>/dev/null | grep -q '^i'

Gibt true zurück (Exit-Status 0im Shell-Skript), wenn das Paket installiert ist, 1andernfalls false (Exit-Status ).

  • -Wbedeutet "Anzeigen" ( dpkg-querymuss eine angeforderte Aktion haben).
  • -f ändert das Format der Ausgabe.
  • db:Status-abbrev ist die Kurzform des Paketstatus.
  • 2>/dev/nullStummschalten, dpkg-querywenn ein ungültiger Paketname angegeben wird. Wie damit umgegangen werden soll, kann von Fall zu Fall sein.
  • grep -q Gibt true zurück, wenn eine Übereinstimmung vorliegt, andernfalls false.

Wenn es häufig verwendet wird, kann es zu einer einfachen Funktion gemacht werden:

#!/bin/sh
debInst() {
    dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
}

if debInst "$1"; then
    printf 'Why yes, the package %s _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package %s is not currently installed.\n' "$1"
fi

oder einfach nur

#!/bin/sh
if dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'; then
    printf 'Why yes, the package "%s" _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package "%s" is not currently installed.\n' "$1"
fi

Obwohl dies zweifellos richtig ist, finde ich, dass dies dpkg-query -l "$package" | grep -q ^.inormalerweise ausreichend ist (und leichter zu merken ist).
Phogg

1
@phogg: Ja, hängt davon ab, ob es in einem Skript leben soll oder nicht. Außerdem ist die dpkg-query -lAusgabe nicht in Stein gemeißelt, da es sich nur um einen Benutzerpräsentationsmodus handelt. Wenn sich die Präsentation ändert, kann ein solches Skript möglicherweise beschädigt werden.
Daniel Andersson

@ Daniel. Ich mag den Rückkehrcode-Ansatz. Bitte sehen Sie meine Antwort mit Details im Code.
Tahoar

Am 10.04 scheint die Formatoption db: Status-Abkürzung nicht zu existieren - ich habe verwendet: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'mit dem gleichen Effekt.
Scottynomad

1

Ich habe Daniels Vorschläge an drei Paketen mit folgenden Ergebnissen getestet:

  1. Native Debian-Repository-Paket nicht installiert:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. Auf dem Host registriertes und installiertes PPA-Paket:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. Auf dem Host registriertes, aber nicht installiertes PPA-Paket:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' domy-ce
    ~$ echo $?
    0
    ~$ sudo apt-get remove domy-ce
    [sudo] password for user: 
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    Package domy-ce is not installed, so not removed
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
    

Obwohl mir der Ansatz gefällt, kann ich dem Rückkehrcode bei PPA-Paketen anscheinend nicht vertrauen. Abgesehen davon denke ich, dass ich mich daran halten werde, die Rückgabe des apt-cache policyBefehls zu analysieren .


Nun, Ihre Codebeispiele sind nicht das, was ich Ihnen gesagt habe, aber ich denke, Sie haben gerade den grepTeil in Ihrem Einfügen verpasst . Ich kann Ihr Problem nicht wirklich reproduzieren, aber das könnte daran liegen, dass die Codebeispiele derzeit unvollständig sind. Beheben Sie das bitte. Führen Sie Debian oder Ubuntu aus?
Daniel Andersson

Ich verwende Ubuntu 10.04 (werden PPAs ohne reines Debian unterstützt?). Mein Code hat Ihr grep gelöscht, weil 1) der Befehl dkpg-query nichts in stdout schreibt und grep immer einen Rückkehrcode auslöst. Der Rückkehrcode für dpkg-query ist bei Installation 0.
Tahoar

2
1. Kennzeichnen Sie Ihren Beitrag dann nicht mit "Debian". 2. Ich glaube nicht, dass Sie die grepim Befehl gespielte Rolle verstanden haben , also haben Sie sie entfernt, und jetzt sagen Sie, dass sie nicht funktioniert? grep -qgibt den Rückkehrcode zurück, 1wenn er nicht übereinstimmt, dh das Programm nicht installiert oder nicht verfügbar ist oder 0wenn das Programm installiert ist. Das habe ich in meinem Beitrag erklärt.
Daniel Andersson

1
#!/bin/bash

# Check for dependencies 
check_deps () {
DEPS=$(echo {dialog,sqlite3,openssh-client})
for i in $DEPS ; do
    dpkg-query -W -f='${Package}\n' | grep ^$i$ > /dev/null
    if [ $? != 0 ] ; then
        echo "Installing deps ..."
        aptitude install $i -y > /dev/null
    fi
done  
}

# execute the check_deps function
check_deps

-1, die Frage betrifft nicht die Abhängigkeitsprüfung. Erklären Sie auch, was die Teile des Befehls tun: Andernfalls können andere Personen nicht sehen, was los ist.
Daniel Andersson

DEPS=$(echo {dialog,sqlite3,openssh-client})kann gleichwertig als gerecht geschrieben werden DEPS="dialog sqlite3 openssh-client".
Daniel Andersson

1

Ich mag Daniel Anderssons Antwort, aber es hat bei mir nicht funktioniert. Ich bin auf Ubuntu 12.04.

Von der dpkg - man - Seite , db:Status-abbrevfunktioniert nur in dpkg 1.16.2+:

          db:Status-Abbrev
                 It  contains the abbreviated package status, such as “ii”
                 (since dpkg 1.16.2).

Meine Lösung bestand darin, altes Verhalten zu verwenden, nur den StatusFormatierer:

dpkg-query -Wf'${Status}' {my_pkg_name}

Ausgänge

install ok installed 

Ich vermute, dies war die Inspiration für "ii" in anderen Darstellungen.

Um Daniel Anderssons Antwort vollständig an die Arbeit an älteren Versionen von dpkg und damit an älteren Ubuntu-Distributionen anzupassen:

dpkg-query -Wf'${Status}' {your_pkg_name} 2>/dev/null | grep -q "install ok installed"

Kehrt zurück:

  • 0 - Paket ist installiert, oder
  • 1 - Paket ist NICHT installiert.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.