Tester si un package est installé dans APT

10

Je veux une méthode de script shell pour tester / signaler si un package est installé. Je n'ai pas besoin de détails, seulement un retour booléen pour définir le flux logique. J'ai regardé Rechercher si un paquet est installé , mais dpkgrenvoie une sortie complexe et son format change selon que le paquet est dans le référentiel Debian ou dans un PPA Ubuntu.

J'ai trouvé que apt-cachecela faisait un très bon travail et j'ai trouvé cette méthode:

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

Quelqu'un connaît-il un moyen plus simple ou plus direct?

tahoar
la source

Réponses:

12

dpkg-query comme dans votre article lié semble être l'outil le plus correct pour le travail, sauf en utilisant par exemple les bibliothèques Python disponibles pour se lier directement au système APT dans un tel contexte de script.

Avec dpkg-query:

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

Renvoie true (état de sortie 0dans le script shell) si le package est installé, false (état de sortie 1) sinon.

  • -Wsignifie "Afficher" ( dpkg-querydoit avoir une action demandée).
  • -f change le format de la sortie.
  • db:Status-abbrev est la forme abrégée du statut du package.
  • 2>/dev/nullfait taire dpkg-querysi un nom de package non valide est donné. La façon dont cela devrait être géré pourrait être une question au cas par cas.
  • grep -q renvoie vrai s'il y a correspondance, faux sinon.

S'il est souvent utilisé, il pourrait devenir une simple fonction:

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

ou tout simplement

#!/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
Daniel Andersson
la source
Bien que cela soit sans aucun doute correct, je trouve que dpkg-query -l "$package" | grep -q ^.ic'est généralement suffisant (et plus facile à retenir).
phogg
1
@phogg: Oui, cela dépend s'il est censé vivre dans un script ou non. En outre, la dpkg-query -lsortie n'est pas figée car il s'agit simplement d'un mode de présentation utilisateur, donc si la présentation change, un tel script pourrait se casser.
Daniel Andersson
@Daniel. J'aime l'approche du code retour. Veuillez voir ma réponse avec des détails dans le code.
tahoar
Le 10.04, l'option de format db: Status-abbrev ne semble pas exister - j'ai utilisé: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'dans le même sens.
scottynomad
1

J'ai testé les suggestions de Daniel sur trois packages avec ces résultats:

  1. Paquet de référentiel Debian natif non installé:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. Package PPA enregistré sur l'hôte et installé:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. Package PPA enregistré sur l'hôte mais non installé:

    ~$ 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.
    

Bien que j'aime l'approche, il semble que je ne puisse pas faire confiance au code de retour avec les packages PPA. Bref, je pense que je vais m'en tenir à l'analyse du retour de la apt-cache policycommande.

tahoar
la source
Eh bien, vos exemples de code ne sont pas ce que j'ai dit que vous devriez faire, mais je suppose que vous venez de manquer la greppartie de votre collage. Je ne peux pas vraiment reproduire votre problème, mais cela peut être dû au fait que les exemples de code sont actuellement incomplets, veuillez donc corriger cela. Exécutez-vous Debian ou Ubuntu?
Daniel Andersson
J'utilise Ubuntu 10.04 (les PPA ne prennent-ils pas en charge Debian directement?). Mon code a laissé tomber votre grep car 1) la commande dkpg-query n'écrit rien sur stdout et grep lance toujours un code retour. Le code retour dpkg-query est 0 s'il est installé.
tahoar
2
1. Ne marquez pas votre article "Debian" alors. 2. Je ne pense pas que vous ayez compris le rôle grepjoué dans la commande, vous l'avez donc supprimé et maintenant vous dites que cela ne fonctionne pas? grep -qdonne le code retour 1s'il ne correspond pas , c'est-à-dire que le programme n'est pas installé ou indisponible, ou 0si le programme est installé. Je l'ai expliqué dans mon post.
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
Diego Roberto Dos Santos
la source
-1, la question ne concerne pas la vérification des dépendances. Expliquez également ce que font les différentes parties de la commande: sinon les autres personnes ne peuvent pas voir ce qui se passe.
Daniel Andersson
DEPS=$(echo {dialog,sqlite3,openssh-client})peut être écrit de manière équivalente comme juste DEPS="dialog sqlite3 openssh-client".
Daniel Andersson
1

J'aime la réponse de Daniel Andersson, mais cela n'a pas fonctionné pour moi. Je suis sur Ubuntu 12.04.

Depuis la page de manuel de dpkg , db:Status-abbrevne fonctionne que dans dpkg 1.16.2+:

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

Ma solution a été d'utiliser un comportement hérité, juste le Statusformateur:

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

les sorties

install ok installed 

Je suppose que c'était l'inspiration de "ii" dans d'autres représentations.

Donc, pour adapter complètement la réponse de Daniel Andersson pour travailler sur une ancienne version de dpkg, et donc sur des distributions Ubuntu plus anciennes:

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

Retour:

  • 0 - le package est installé, ou
  • 1 - le package n'est PAS installé.
Wilbur Whateley
la source