it-swarm.com.de

Überprüfen Sie, ob ein apt-get-Paket installiert ist, und installieren Sie es dann, wenn es nicht unter Linux läuft

Ich arbeite an einem Ubuntu-System und derzeit mache ich das:

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 Leute tun würden? Oder gibt es eine elegantere Lösung?

196
John Jiang

Um zu prüfen, ob packagename installiert wurde, geben Sie Folgendes ein:

dpkg -s <packagename>

Sie können auch dpkg-query verwenden, der zu Ihrem Zweck eine ordentlichere Ausgabe hat und auch Platzhalterzeichen akzeptiert.

dpkg-query -l <packagename>

Um herauszufinden, welches Paket die command besitzt, versuchen Sie Folgendes:

dpkg -S `which <command>`

Weitere Informationen finden Sie in Artikel Finden Sie heraus, ob das Paket unter Linux installiert ist und dpkg Cheat Sheet .

289
Török Gábor

Um es etwas expliziter zu machen, hier ein kleines Bash-Skript, das nach einem Paket sucht und es bei Bedarf installiert. Sie können natürlich auch andere Dinge tun, wenn Sie feststellen, dass das Paket fehlt, z. B. einfach mit einem Fehlercode beenden.

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 ausgeführt wird (z. B. ein Nautilus-Skript), möchten Sie wahrscheinlich den Aufruf von "Sudo" durch einen "Gksudo" -Aufruf ersetzen.

72
Urhixidur

Dieser Einzeiler gibt 1 (installiert) oder 0 (nicht installiert) für das Nano-Paket zurück.

$(dpkg-query -W -f='${Status}' nano 2>/dev/null | grep -c "ok installed")

auch wenn das Paket nicht existiert/nicht verfügbar ist.

Das folgende Beispiel installiert das Paket 'nano', falls 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
61
Seb

Ich biete dieses Update an, da Ubuntu sein "Personal Package Archive" (PPA) hinzugefügt hat, als diese Frage beantwortet wurde und PPA-Pakete ein anderes Ergebnis haben.

  1. Natives Debian-Repository-Paket nicht installiert:

    ~$ dpkg-query -l Apache-Perl
    ~$ echo $?
    1
    
  2. Auf dem Host registriertes und installiertes PPA-Paket:

    ~$ dpkg-query -l libreoffice
    ~$ echo $?
    0
    
  3. Auf dem Host registriertes PPA-Paket, jedoch nicht installiert:

    ~$ 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.
    

Ebenfalls veröffentlicht am: https://superuser.com/questions/427318/test-if-a-package-is-installed-in-apt/427898

11
tahoar

UpAndAdam schrieb:

Allerdings können Sie sich hier beim Scripting nicht einfach auf Rückgabewerte verlassen

In mein Erfahrung verlassen Sie sich can auf den Exit-Code von dkpg.

Der Rückkehrcode von dpkg -s lautet 0, wenn das Paket installiert ist, und 1, falls dies nicht der Fall ist. Die einfachste Lösung, die ich gefunden habe, war:

dpkg -s <pkg-name> 2>/dev/null >/dev/null || Sudo apt-get -y install <pkg-name>

Funktioniert gut für mich ...

7
rocka84

Das scheint ziemlich gut zu funktionieren.

$ Sudo dpkg-query -l | grep <some_package_name> | wc -l
  • Es gibt entweder 0 zurück, wenn es nicht installiert ist, oder eine Nummer > 0, falls installiert.
6
sandman

Ich habe festgestellt, dass alle obigen Lösungen zu einem falschen Ergebnis führen können, wenn ein Paket installiert und dann entfernt wird, das Installationspaket jedoch noch auf dem System verbleibt.

So replizieren Sie: Installationspaket apt-get install curl
Paket apt-get remove curl entfernen

Testen Sie jetzt die obigen 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 führt zu einem definitiven installiert oder nicht installiert

3
Mark

dpkg -s programmatische Verwendung

Ich mag dpkg -s, da er mit dem Status 1 beendet wird, wenn eines der Pakete nicht installiert ist, was es einfach macht, es zu automatisieren:

pkgs='qemu-user pandoc'
if ! dpkg -s $pkgs >/dev/null 2>&1; then
  Sudo apt-get install $pkgs
fi

Siehe auch:

Getestet auf Ubuntu 18.10.

$name="rsync"

[ `which $name` ] $$ echo "$name : installed" || Sudo apt-get install -y $name
2
Kyprio

Ich habe mich für eine Lösung entschieden, basierend auf Nultyis 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

Grundsätzlich ist die Fehlermeldung von dpkg --get-selections viel einfacher zu analysieren als die meisten anderen, da sie keine Statusangaben wie "deinstall" enthält. Es kann auch mehrere Pakete gleichzeitig prüfen, was Sie nicht nur mit Fehlercodes tun können.

Erklärung/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 entfernt grep installierte Pakete aus der Liste, und awk holt die Paketnamen aus der Fehlermeldung heraus, was MISSING='python3-venv python3-dev jq' zur Folge hat, das in einen Installationsbefehl eingefügt werden kann.

Ich gebe nicht blindlings einen apt-get install $PACKAGES aus, da, wie in den Kommentaren erwähnt, Pakete, die Sie nicht geplant haben, unerwartet aktualisiert werden können. Nicht wirklich eine gute Idee für automatisierte Prozesse, von denen erwartet wird, dass sie stabil sind.

2
Izkata

Das wird es tun. apt-get install ist idempotent.

Sudo apt-get install command
2
David Baucum

Benutzen:

apt-cache policy <package_name>

Wenn es nicht installiert ist, wird Folgendes angezeigt:

Installed: none

Ansonsten wird es zeigen:

Installed: version
2

Diese Funktion ist bereits in Ubuntu und Debian im Paketcommand-not-foundenthalten.

1
camh
apt list [packagename]

scheint die einfachste Möglichkeit zu sein, dies außerhalb von dpkg und älteren apt- * -tools zu tun

1
Erich

Für Ubuntu bietet apt eine recht anständige Möglichkeit, 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 leite die Fehlerausgabe auf null um, weil apt davor warnt, die "unstable cli" zu verwenden. Ich vermute, dass das Listenpaket stabil ist, daher denke ich, dass es in Ordnung ist, diese Warnung wegzuwerfen. Das -qq macht apt super leise.

1
carlin.scott

Ich hatte eine ähnliche Anforderung, wenn der Test lokal statt im Docker ausgeführt wurde. Grundsätzlich wollte ich nur gefundene .deb-Dateien installieren, wenn sie nicht bereits installiert waren. 

# 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, das einzige Problem, das ich sehen kann, ist, dass die Versionsnummer des Pakets nicht überprüft wird. Wenn die .deb-Datei eine neuere Version ist, wird dadurch das aktuell installierte Paket nicht überschrieben.

1
Craig

Es scheint, dass heutzutage apt-get eine Option --no-upgrade hat, die genau das tut, was das OP will:

--no-upgrade Aktualisieren Sie keine Pakete. In Verbindung mit der Installation verhindert das Nicht-Upgrade, dass die aufgelisteten Pakete aktualisiert werden, wenn sie bereits installiert sind.

Manpage von https://linux.die.net/man/8/apt-get

Daher können Sie verwenden

apt-get install --no-upgrade package

und package werden nur installiert, wenn dies nicht der Fall ist.

0

Viele Dinge wurden erzählt, aber für mich ist der einfachste Weg:

dpkg -l | grep packagename
0
freedev
which <command>
if [ $? == 1 ]; then
    <pkg-manager> -y install <command>
fi
0
irock.dev

Ich benutze den folgenden Weg: 

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
0
Nitish Jadia

In Bash:

PKG="emacs"
dpkg-query -l $PKG > /dev/null || Sudo apt install $PKG

Beachten Sie, dass Sie in PKG eine Zeichenfolge mit mehreren Paketen haben können.

0
daruma

Dieser Befehl ist der denkwürdigste:

dpkg --get-selections <package-name>

Wenn es installiert ist, wird gedruckt:

<Paketname> installieren

Sonst druckt es

Es wurden keine Pakete gefunden, die mit <Paketname> übereinstimmen.

Dies wurde auf Ubuntu 12.04.1 (Precise Pangolin) getestet.

0
iNulty