web-dev-qa-db-fra.com

Vérifiez si un paquet apt-get est installé, puis installez-le s'il n'est pas sous Linux?

Je travaille sur un système Ubuntu et voici ce que je fais actuellement:

if ! which command > /dev/null; then
   echo -e "Command not found! Install? (y/n) \c"
   read
   if "$REPLY" = "y"; then
      Sudo apt-get install command
   fi
fi

Est-ce ce que la plupart des gens feraient? Ou existe-t-il une solution plus élégante?

196
John Jiang

Pour vérifier si packagename a été installé, tapez:

dpkg -s <packagename>

Vous pouvez également utiliser dpkg-query qui a une sortie plus nette et accepte les caractères génériques.

dpkg-query -l <packagename>

Pour trouver quel paquet possède la command, essayez:

dpkg -S `which <command>`

Pour plus de détails, voir l'article Découvrez si le paquet est installé sous Linux et dpkg cheat sheet .

289
Török Gábor

Pour être un peu plus explicite, voici un peu de script bash qui recherche un paquet et l’installe si nécessaire. Bien sûr, vous pouvez faire autre chose lorsque vous constatez que le paquet est manquant, comme simplement quitter avec un code d'erreur.

PKG_OK=$(dpkg-query -W --showformat='${Status}\n' the.package.name|grep "install ok installed")
echo Checking for somelib: $PKG_OK
if [ "" == "$PKG_OK" ]; then
  echo "No somelib. Setting up somelib."
  Sudo apt-get --force-yes --yes install the.package.name
fi

Si le script s'exécute dans une interface graphique (par exemple, il s'agit d'un script Nautilus), vous souhaiterez probablement remplacer l'invocation "Sudo" par une invocation "gksudo".

72
Urhixidur

Ce one-liner renvoie 1 (installé) ou 0 (non installé) pour le package "nano".

$(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed")

même si le paquet n'existe pas/n'est pas disponible.

L'exemple ci-dessous installe le package 'nano' s'il n'est pas installé.

if [ $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed") -eq 0 ];
then
  apt-get install nano;
fi
61
Seb

J'offre cette mise à jour car Ubuntu a ajouté son "Archive de paquet personnel" (PPA) au moment même où cette question a reçu une réponse, et les paquets de PPA ont un résultat différent.

  1. Le package de référentiel Debian natif n'est pas installé:

    ~$ dpkg-query -l Apache-Perl
    ~$ echo $?
    1
    
  2. Paquet PPA enregistré sur l'hôte et installé:

    ~$ dpkg-query -l libreoffice
    ~$ echo $?
    0
    
  3. Paquet PPA enregistré sur l'hôte mais non installé:

    ~$ dpkg-query -l 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.
    

Également publié sur: https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt/427898

11
tahoar

UpAndAdam a écrit:

Cependant, vous ne pouvez pas simplement compter sur les codes de retour ici pour les scripts

Dans mon expérience, vous pouvez vous fier aux codes de sortie de dkpg.

Le code de retour de dpkg -s est 0 si le paquet est installé et 1 s'il ne l'est pas, la solution la plus simple que j'ai trouvée était:

dpkg -s <pkg-name> 2>/dev/null >/dev/null || Sudo apt-get -y install <pkg-name>

Cela fonctionne bien pour moi ...

7
rocka84

Cela semble bien fonctionner.

$ Sudo dpkg-query -l | grep <some_package_name> | wc -l
  • Il renvoie soit 0 s'il n'est pas installé, soit un nombre > 0 s'il est installé.
6
sandman

J'ai trouvé que toutes les solutions ci-dessus peuvent produire un faux positif si un paquet est installé puis supprimé, mais le paquet d'installation reste sur le système.

Pour répliquer: Installez le package apt-get install curl
Supprimer le package apt-get remove curl

Maintenant, testez les réponses ci-dessus.

La commande suivante semble résoudre cette condition:
dpkg-query -W -f='${Status}\n' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'

Cela entraînera un installed ou not-installed définitif

3
Mark

dpkg -s usage programmatique

J'aime dpkg -s car il existe avec le statut 1 si l'un des paquetages n'est pas installé, ce qui facilite son automatisation:

pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
  Sudo apt-get install $pkgs
fi

Voir également:

Testé sur Ubuntu 18.10.

$name="rsync"

[ `which $name` ] $$ echo "$name : installed" || Sudo apt-get install -y $name
2
Kyprio

J'ai choisi une solution basée sur La réponse de Nultyi :

MISSING=$(dpkg --get-selections $PACKAGES 2>&1 | grep -v 'install$' | awk '{ print $6 }')
# Optional check here to skip bothering with apt-get if $MISSING is empty
Sudo apt-get install $MISSING

Fondamentalement, le message d'erreur de dpkg --get-selections est beaucoup plus facile à analyser que la plupart des autres, car il n'inclut pas de statuts tels que "deinstall". Il peut également vérifier plusieurs paquets simultanément, ce que vous ne pouvez pas faire avec des codes d'erreur.

Explication/exemple:

$ dpkg --get-selections  python3-venv python3-dev screen build-essential jq
dpkg: no packages found matching python3-venv
dpkg: no packages found matching python3-dev
screen                                          install
build-essential                                 install
dpkg: no packages found matching jq

Donc, grep supprime les packages installés de la liste et awk extrait les noms de package du message d'erreur, ce qui entraîne MISSING='python3-venv python3-dev jq', qui peut être inséré de manière triviale dans une commande d'installation.

Je n'émets pas aveuglément un apt-get install $PACKAGES car, comme indiqué dans les commentaires, cela peut mettre à jour de manière inattendue des paquets que vous n'aviez pas prévus; pas vraiment une bonne idée pour les processus automatisés qui devraient être stables.

2
Izkata

Cela va le faire. apt-get install est idempotent.

Sudo apt-get install command
2
David Baucum

Utilisation:

apt-cache policy <package_name>

S'il n'est pas installé, il affichera:

Installed: none

Sinon, cela montrera:

Installed: version
2
Mohammed Noureldin

Cette fonctionnalité existe déjà dans Ubuntu et Debian, dans le paquetcommand-not-found.

1
camh
apt list [packagename]

semble être le moyen le plus simple de le faire en dehors de dpkg et des anciens outils apt- *

1
Erich

J'avais une exigence similaire lors de l'exécution du test localement au lieu de dans le menu fixe. En gros, je voulais uniquement installer les fichiers .deb trouvés s'ils n'étaient pas déjà installés. 

# If there are .deb files in the folder, then install them
if [ `ls -1 *.deb 2> /dev/null | wc -l` -gt 0 ]; then
  for file in *.deb; do
    # Only install if not already installed (non-zero exit code)
    dpkg -I ${file} | grep Package: | sed -r 's/ Package:\s+(.*)/\1/g' | xargs dpkg -s
    if [ $? != 0 ]; then
        dpkg -i ${file}
    fi;
  done;
else
  err "No .deb files found in '$PWD'"
fi

Je suppose que le seul problème que je vois est qu’il ne vérifie pas le numéro de version du package. Par conséquent, si le fichier .deb est une version plus récente, le package actuellement installé ne sera pas écrasé.

1
Craig

Il semble qu’aujourd’hui, apt-get dispose d’une option --no-upgrade qui ne fait que ce que le PO veut:

--no-upgrade Ne pas mettre à jour les paquets. Lorsqu'elle est utilisée conjointement avec install, no-upgrade empêchera les packages répertoriés d'être mis à niveau s'ils sont déjà installés.

Manpage from https://linux.die.net/man/8/apt-get

Par conséquent, vous pouvez utiliser

apt-get install --no-upgrade package

et package ne sera installé que si ce n'est pas le cas.

0

Beaucoup de choses ont été dites, mais pour moi, le plus simple est:

dpkg -l | grep packagename
0
freedev
which <command>
if [ $? == 1 ]; then
    <pkg-manager> -y install <command>
fi
0
irock.dev

J'utilise la manière suivante: 

which mySQL 2>&1|tee 1> /dev/null
  if [[ "$?" == 0 ]]; then
                echo -e "\e[42m MySQL already installed. Moving on...\e[0m"
        else
        Sudo apt-get install -y mysql-server
                if [[ "$?" == 0 ]]; then
                        echo -e "\e[42mMy SQL installed\e[0m"
                else
                        echo -e "\e[42Installation failed\e[0m"
                fi
        fi
0
Nitish Jadia

Dans Bash:

PKG="emacs"
dpkg-query -l $PKG > /dev/null || Sudo apt install $PKG

Notez que vous pouvez avoir une chaîne avec plusieurs packages dans PKG.

0
daruma

Cette commande est la plus mémorable:

dpkg --get-selections <package-name>

S'il est installé, il imprime:

<nom du paquet> install

Sinon, il imprime

Aucun paquet trouvé ne correspond à <nom du paquet>.

Ceci a été testé sur Ubuntu 12.04.1 (Precise Pangolin).

0
iNulty