dpkg-query --showformat='${db:Status-Status}'
Cela produit une petite chaîne de sortie qui n'est pas susceptible de changer et qui est facile à comparer de manière déterministe sans grep
:
pkg=hello
status="$(dpkg-query -W --showformat='${db:Status-Status}' "$pkg" 2>&1)"
if [ ! $? = 0 ] || [ ! "$status" = installed ]; then
sudo apt install $pkg
fi
En $? = 0
est nécessaire car si vous n'avez jamais installé un paquet auparavant, et après avoir supprimé certains paquets tels que hello
, dpkg-query
quitte avec le statut 1 et sort sur stderr :
dpkg-query: no packages found matching hello
au lieu de sortir not-installed
. En 2>&1
capte également ce message d'erreur lorsqu'il s'agit d'empêcher le passage au terminal.
Pour les paquets multiples :
pkgs='hello certbot'
install=false
for pkg in $pkgs; do
status="$(dpkg-query -W --showformat='${db:Status-Status}' "$pkg" 2>&1)"
if [ ! $? = 0 ] || [ ! "$status" = installed ]; then
install=true
break
fi
done
if "$install"; then
sudo apt install $pkgs
fi
Les statuts possibles sont documentés dans man dpkg-query
comme :
n = Not-installed
c = Config-files
H = Half-installed
U = Unpacked
F = Half-configured
W = Triggers-awaiting
t = Triggers-pending
i = Installed
Les versions à une seule lettre sont disponibles avec db:Status-Abbrev
mais ils sont associés à l'action et à l'état d'erreur, ce qui donne 3 caractères et nécessite de les couper.
Je pense donc qu'il est suffisamment fiable de se fier aux statuts non capitalisés ( Config-files
vs config-files
) ne change pas à la place.
dpkg -s
statut de sortie
Malheureusement, cela ne répond pas aux attentes de la plupart des utilisateurs :
pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
sudo apt-get install $pkgs
fi
car pour certains paquets, par exemple certbot
, faire :
sudo apt install certbot
sudo apt remove certbot
feuilles certbot
en état config-files
ce qui signifie que les fichiers de configuration ont été laissés dans la machine. Et dans cet état, dpkg -s
revient toujours 0
car les métadonnées du paquet sont toujours conservées afin que les fichiers de configuration puissent être gérés de manière plus efficace.
Pour faire réellement dpkg -s
retourner 1 comme souhaité, --purge
serait nécessaire :
sudo apt remove --purge certbot
qui le déplace en fait dans not-installed
/ dpkg-query: no packages found matching
.
Notez que seuls certains paquets laissent des fichiers de configuration derrière eux. Un paquet plus simple comme hello
va directement de installed
a not-installed
sin --purge
.
Testé sur Ubuntu 20.10.
Python apt
paquet
Il existe un paquetage Python 3 pré-installé appelé apt
dans Ubuntu 18.04 qui expose une interface apt Python !
Un script qui vérifie si un paquet est installé et l'installe sinon peut être vu à : https://stackoverflow.com/questions/17537390/how-to-install-a-package-using-the-Python-apt-api/17538002#17538002
Voici une copie à titre de référence :
#!/usr/bin/env python
# aptinstall.py
import apt
import sys
pkg_name = "libjs-yui-doc"
cache = apt.cache.Cache()
cache.update()
cache.open()
pkg = cache[pkg_name]
if pkg.is_installed:
print "{pkg_name} already installed".format(pkg_name=pkg_name)
else:
pkg.mark_install()
try:
cache.commit()
except Exception, arg:
print >> sys.stderr, "Sorry, package installation failed [{err}]".format(err=str(arg))
Vérifier si un exécutable est dans PATH
au lieu de
Voir : https://stackoverflow.com/questions/592620/how-can-i-check-if-a-program-exists-from-a-bash-script/22589429#22589429
Voir aussi