Vérifiez si un paquet apt-get est installé, puis l'installer si ce n'est pas sur Linux?
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?
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.
-
package de dépôt Debian natif 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 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.