Überprüfen Sie, ob ein apt-get-Paket installiert wird und es dann installieren, wenn es nicht auf Linux ist?
Frage
Ich arbeite an einem Ubuntu-System und zur Zeit ist das, was ich tue:
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
Ist das, was die meisten Menschen tun würde? Oder gibt es eine elegantere Lösung?
Lösung
Um zu überprüfen, ob packagename
installiert wurde, geben Sie:
dpkg -s <packagename>
Sie können auch verwenden dpkg-query
, die eine sauberere Ausgabe für Ihren Zweck hat und akzeptiert Wildcards, auch.
dpkg-query -l <packagename>
Für welches Paket die command
besitzt, versuchen Sie:
dpkg -S `which <command>`
Weitere Informationen finden Sie im Artikel Finden Sie heraus, wenn die Verpackung in Linux installiert ist und dpkg Spickzettel .
Andere Tipps
Um ein wenig mehr explizit zu sein, hier ist ein wenig Bash-Skript, das für ein Paket überprüft und installiert sie, falls erforderlich. Natürlich können Sie auch andere Dinge tun, auf der Suche nach, dass das Paket fehlt, wie einfach mit einem Fehlercode beendet wird.
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
Wenn das Skript innerhalb einer GUI läuft (zum Beispiel ist es ein Nautilus-Skript), werden Sie wahrscheinlich die ‚sudo‘ Aufruf mit ‚sudo‘ ersetzen möchten ein.
Dieser Einzeiler gibt 1 (installiert) oder 0 (nicht vorhanden) für das 'Nano' Paket ..
$(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed")
, selbst wenn das Paket nicht vorhanden ist / ist nicht verfügbar.
Das folgende Beispiel installiert die ‚Nano‘ Paket, wenn es nicht installiert ist ..
if [ $(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed") -eq 0 ];
then
apt-get install nano;
fi
Ich biete dieses Update seit Ubuntu seiner „Personal Package Archive“ (PPA) hinzugefügt wie diese Frage beantwortet wurde, und PPA-Pakete haben ein anderes Ergebnis.
-
Native Debian-Repository-Paket nicht installiert ist:
~$ dpkg-query -l apache-perl ~$ echo $? 1
-
PPA-Paket auf dem Host registriert und installiert:
~$ dpkg-query -l libreoffice ~$ echo $? 0
-
PPA-Paket auf dem Host registriert, aber nicht installiert ist:
~$ 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.
Auch posted an: https://superuser.com / Fragen / 427.318 / Test-if-a-Paket-wird-installiert-in-apt / 427.898
dpkg -s
programmtechnische Verwendung
Ich mag dpkg -s
wie es mit dem Status 1
beendet, wenn eine der Pakete nicht installiert ist, macht es einfach, es zu automatisieren:
pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
sudo apt-get install $pkgs
fi
man dpkg
dokumentiert nicht den Exit-Status leider, aber ich denke, es sollte ziemlich sicher sein, darauf verlassen:
-s, --status package-name...
Report status of specified package.
Siehe auch:
- https: // askubuntu .com / Fragen / 423355 / wie-do-i-Check-if-a-Paket-wird-installiert-on-my-Server
Getestet auf Ubuntu 18.10.
UpAndAdam schrieb:
Sie können jedoch nicht einfach verlassen Rückgabecodes hier für Skripting
In mein Erfahrung, die Sie auf können setzen auf dkpg die Exit-Codes.
Der Rückgabecode von dpkg es ist 0 , wenn das Paket installiert ist und 1 , wenn es nicht ist, so die einfachste Lösung fand ich war:
dpkg -s <pkg-name> 2>/dev/null >/dev/null || sudo apt-get -y install <pkg-name>
funktioniert gut für mich ...
Das scheint ziemlich gut zu funktionieren.
$ sudo dpkg-query -l | grep <some_package_name> | wc -l
- Es gibt entweder
0
wenn nicht installiert oder eine bestimmte Anzahl> 0
falls installiert.
ich alle oben genannten Lösungen gefunden haben, kann ein falsch positives erzeugen, wenn ein Paket installiert wird und dann entfernt noch das Installationspaket bleibt auf dem System.
So zu replizieren:
Installieren Sie das Paket apt-get install curl
Entfernen Sie Paket apt-get remove curl
Jetzt testen oben Antworten.
Der folgende Befehl scheint diese Bedingung zu lösen:
dpkg-query -W -f='${Status}\n' curl | head -n1 | awk '{print $3;}' | grep -q '^installed$'
Dies in einem endgültigen führen installiert oder nicht installiert
Ich habe auf einer siedelt basierend auf Nultyi Antwort :
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
Im Grunde genommen ist die Fehlermeldung von dpkg --get-selections
viel einfacher zu analysieren, als die meisten anderen, weil es wie „deinstallieren“ nicht Zustände umfassen. Es kann auch mehrere Pakete gleichzeitig überprüfen, etwas, das Sie nicht nur mit Fehlercodes tun können.
Erläuterung / Beispiel:
$ 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
So grep entfernt Pakete aus der Liste installiert, und awk zieht die Paketnamen aus der Fehlermeldung, in MISSING='python3-venv python3-dev jq'
führt, was trivialerweise in einen Installationsbefehl eingefügt werden kann.
Ich bin die Ausgabe nicht blind eine apt-get install $PACKAGES
, weil, wie in den Kommentaren erwähnt, diese unerwartet Pakete aktualisieren können Sie nicht auf planten; nicht wirklich eine gute Idee für automatisierte Prozesse, die stabil sein dürften.
$name="rsync"
[ `which $name` ] $$ echo "$name : installed" || sudo apt-get install -y $name
Dies wird es tun. apt-get install
ist idempotent.
sudo apt-get install command
Verwendung:
apt-cache policy <package_name>
Wenn es nicht installiert ist, wird es zeigen:
Installed: none
Sonst wird es zeigen:
Installed: version
Diese Funktion existiert bereits in Ubuntu und Debian, in dem command-not-found
Paket.
apt list [packagename]
scheint der einfachste Weg, es zu tun, außerhalb von dpkg und ältere apt- * Werkzeuge
which <command>
if [ $? == 1 ]; then
<pkg-manager> -y install <command>
fi
Ich hatte eine ähnliche Anforderung bei der Prüfung vor Ort statt in Docker läuft. Im Grunde wollte ich nur gefunden keine .deb-Dateien installieren, wenn sie nicht bereits installiert wurden.
# 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
Ich denke, sie nur Problem, das ich sehe, ist, dass es nicht die Versionsnummer des Pakets überprüft so, ob .deb-Datei eine neuere Version ist, dann ist dies das derzeit installierte Paket nicht überschreiben würde.
Für Ubuntu apt bietet eine recht ordentliche Art und Weise, dies zu tun. Unten ist ein Beispiel für Google Chrome:
apt -qq list google-chrome-stable 2>/dev/null | grep -qE "(installed|upgradeable)" || apt-get install google-chrome-stable
Ich Umleitung Fehlerausgabe auf null, da apt warnt vor seinem „instabil cli“ verwendet wird. Ich vermute, dass die Liste Paket ist stabil, so ich denke, es ist in Ordnung weg, diese Warnung zu werfen. Die -qq macht apt super leise.
Dieser Befehl ist die denkwürdigsten:
dpkg --get-selections <package-name>
Wenn es installiert ist es druckt:
install
Ansonsten druckt
Keine Pakete gefunden
.
Dieses wurde auf Ubuntu 12.04.1 (Precise Pangolin) getestet.
Viele Dinge haben gesagt, für mich einfachste Art und Weise aber ist:
dpkg -l | grep packagename
In Bash:
PKG="emacs"
dpkg-query -l $PKG > /dev/null || sudo apt install $PKG
Beachten Sie, dass Sie eine Zeichenfolge mit mehreren Paketen in PKG haben.
Ich verwende die folgende Art und Weise:
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
Es scheint, dass heute apt-get
hat eine Option --no-upgrade
das genau das tut, was der OP will:
--no-upgrade
nicht Pakete aktualisieren. Wenn in Verbindung mit der Installation wird nicht-Upgrade-Pakete verhindern aufgelistet aktualisiert werden, wenn sie bereits installiert ist.
Manpage von https://linux.die.net/man/8/apt -get
Daher können Sie
apt-get install --no-upgrade package
und package
wird nur installiert werden, wenn es nicht ist.