Vérifiez si un paquet apt-get est installé, puis l'installer si ce n'est pas sur Linux?

StackOverflow https://stackoverflow.com/questions/1298066

  •  18-09-2019
  •  | 
  •  

Question

Je travaille sur un système Ubuntu et actuellement c'est ce que je fais:

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 que la plupart des gens faire? Ou est-il une solution plus élégante?

Était-ce utile?

La solution

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

dpkg -s <packagename>

Vous pouvez également utiliser dpkg-query qui a une sortie plus propre à vos besoins, et accepte les cartes sauvages, aussi.

dpkg-query -l <packagename>

Pour ce paquet est propriétaire du command, essayez:

dpkg -S `which <command>`

Pour plus de détails, voir l'article en savoir si l'emballage est installé dans Linux et antisèche dpkg.

Autres conseils

Pour être un peu plus explicite, voici un peu de script bash qui vérifie un paquet et l'installe si nécessaire. Bien sûr, vous pouvez faire d'autres choses à trouver que le paquet manque, comme sortant simplement 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 est exécuté dans une interface graphique (par exemple, il est un script Nautilus), vous voudrez probablement remplacer l'invocation « sudo » avec un « gksudo » un.

Ceci renvoie one-liner 1 (installée) ou 0 (non installé) pour le paquet '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 paquet « nano » si elle 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

je vous propose cette mise à jour depuis Ubuntu a ajouté son tout comme cette question a été répondu « paquet personnel Archive » (PPA), et les paquets PPA ont un résultat différent.

  1. package de dépôt Debian natif 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 pas 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 posté sur: https://superuser.com / questions / 427318 / test-si-un-paquet est installé en apt / 427898

dpkg -s utilisation programmatique

J'aime dpkg -s sa sortie avec le statut 1 si des paquets n'est pas installé, le rendant facile à l'automatiser:

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

man dpkg ne documente pas l'état de sortie, malheureusement, mais je pense qu'il devrait être raisonnablement sûr de compter sur lui:

-s, --status package-name...
    Report status of specified package.

Voir aussi:

Testé sur Ubuntu 18.10.

UpAndAdam a écrit:

  

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

mon pouvez appuyer sur les codes de sortie de dkpg.

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

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

fonctionne bien pour moi ...

Cela semble fonctionner assez bien.

$ sudo dpkg-query -l | grep <some_package_name> | wc -l
  • soit le rendement 0 en cas d'installation ou d'un numéro > 0 si elle est installée.

J'ai trouvé toutes les solutions ci-dessus peut produire un faux positif si un paquet est installé et enlevé encore le package d'installation reste sur le système.

Pour répliquer: Installer le paquet apt-get install curl
Retirer package apt-get remove curl

Maintenant, testez ci-dessus réponses.

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

Cela se traduira par un définitif installé ou pas installé

Je suis installé sur une fonction de la réponse 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

En gros, le message d'erreur de dpkg --get-selections est beaucoup plus facile à analyser que la plupart des autres, parce qu'il ne comprend pas les statuts comme « deinstall ». Il peut également vérifier plusieurs packages simultanément, quelque chose que vous ne pouvez pas faire avec seulement les 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

grep supprime les paquets installés dans la liste, et awk tire les noms de paquets à partir du message d'erreur, ce qui MISSING='python3-venv python3-dev jq', qui peut être trivialement inséré dans une commande d'installation.

Je ne suis pas aveuglément une émission apt-get install $PACKAGES parce que mentionné dans les commentaires, cela peut inopinément mettre à jour les paquets que vous ne prévoyez pas; pas vraiment une bonne idée pour les processus automatisés qui devraient être stables.

$name="rsync"

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

fera. apt-get install est idempotent.

sudo apt-get install command

Utilisation:

apt-cache policy <package_name>

S'il est pas installé, il indique:

Installed: none

Dans le cas contraire, il affichera:

Installed: version

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

apt list [packagename]

semble être la façon la plus simple de le faire en dehors des anciens outils et dpkg * Apt-

which <command>
if [ $? == 1 ]; then
    <pkg-manager> -y install <command>
fi

J'ai eu une exigence similaire lorsque le test en cours d'exécution au niveau local au lieu de docker. Fondamentalement, je ne voulais installer des fichiers .deb trouvés si elles ne sont 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 qu'ils seul problème que je vois est qu'il ne vérifie pas le numéro de version du package si le fichier .deb est une version plus récente, cela ne serait pas remplacer le paquet actuellement installé.

Pour Ubuntu, apt fournit une façon assez décent de le faire. Voici un exemple pour google chrome:

apt -qq list google-chrome-stable 2>/dev/null | grep -qE "(installed|upgradeable)" || apt-get install google-chrome-stable

Je rediriger la sortie d'erreur null car apt met en garde contre l'utilisation de son « cli instable ». Je soupçonne ensemble de la liste est stable donc je pense qu'il est bon de jeter cet avertissement loin. Le -qq fait apt super calme.

Cette commande est la plus mémorable:

dpkg --get-selections <package-name>

S'il est installé, il affiche:

  

install

Sinon, elle affiche

  

Aucun paquet ne correspond à .

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

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

dpkg -l | grep packagename

Dans Bash:

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

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

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

Il semble que de nos jours apt-get a une --no-upgrade option qui fait exactement ce que l'OP veut:

  

--no-upgrade Ne pas mettre à jour des paquets. Lorsqu'il est utilisé conjointement avec l'installation, sans mise à niveau permettra d'éviter les paquets connus d'être mis à jour si elles sont déjà installées.

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

Par conséquent, vous pouvez utiliser

apt-get install --no-upgrade package

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top