Überprüfen Sie, ob ein apt-get-Paket installiert wird und es dann installieren, wenn es nicht auf Linux ist?

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

  •  18-09-2019
  •  | 
  •  

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?

War es hilfreich?

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.

  1. Native Debian-Repository-Paket nicht installiert ist:

    ~$ dpkg-query -l apache-perl
    ~$ echo $?
    1
    
  2. PPA-Paket auf dem Host registriert und installiert:

    ~$ dpkg-query -l libreoffice
    ~$ echo $?
    0
    
  3. 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:

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top