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?
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 .
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".
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
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.
Le package de référentiel Debian natif n'est pas installé:
~$ dpkg-query -l Apache-Perl
~$ echo $?
1
Paquet PPA enregistré sur l'hôte et installé:
~$ dpkg-query -l libreoffice
~$ echo $?
0
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
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 ...
Cela semble bien fonctionner.
$ Sudo dpkg-query -l | grep <some_package_name> | wc -l
0
s'il n'est pas installé, soit un nombre > 0
s'il est installé.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
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
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.
Cela va le faire. apt-get install
est idempotent.
Sudo apt-get install command
Utilisation:
apt-cache policy <package_name>
S'il n'est pas installé, il affichera:
Installed: none
Sinon, cela montrera:
Installed: version
Cette fonctionnalité existe déjà dans Ubuntu et Debian, dans le paquetcommand-not-found
.
apt list [packagename]
semble être le moyen le plus simple de le faire en dehors de dpkg et des anciens outils apt- *
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é.
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.
Beaucoup de choses ont été dites, mais pour moi, le plus simple est:
dpkg -l | grep packagename
which <command>
if [ $? == 1 ]; then
<pkg-manager> -y install <command>
fi
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
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.
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).