# Shell-Script zum prüfen ob ein Paket installiert ist

## alexander_ro

Hi Mädels ... Jungs ...  :Smile: 

Für ein Shell-Script das nach Bedarf Konfigurationen vornimmt wollte ich auch prüfen lassen ob die nötigen Pakete installiert sind. Meine Idee war mit "qlist -I | grep dhcp" einfach nach dem Paket suchen und dann im Script prüfen ob der zurückgegebene String richtig ist. Leider ist das Ergebnis nicht immer eindeutig. Kennt Ihr vielleicht eine Zuverlässigere Methode wie ich das Prüfen könnte?

Viele Grüße

Alexander

----------

## franzf

eix --installed --exact dhcp sollte doch gehen.

----------

## musv

Ok, wusste gar nicht, dass es auch die Parameter als ausgeschriebene Version gibt. Ich hatte immer:

```
eix -Ie dhcp
```

benutzt. Für die Substring-Suche lässt du halt das e (exact) weg. 

Allerdings kann man auch das o.g. qlist dafür verwenden:

```
qlist -Ic dhcp
```

zeigt zwar nicht soviele Details an, erfüllt aber auch seinen Zweck. 

```
equery l dhcpcd
```

zeigt ebenfalls noch an, ob das Paket installiert ist. Und zur Not kannst du auch noch direkt in der Package-DB suchen:

```
find /var/db/pkg -iname "*dhcp*"
```

Gibt bestimmt noch mehr Möglichkeiten.

----------

## alexander_ro

DIe zwei:

```

eix --installed --exact dhcp

equery l dhcp

```

liefern ein eindeutiges Ergebnis. Wenn ich das richtig gelesen habe liefert eix nur die Textausgabe zurück also keinen Return-Code den ich einfach abfragen könnte. Dann muss ich in der if Abfrage zum feststellen ob das Paket installiert ist nach dem Paketnamen suchen und wenn der nicht da ist eine Meldung ausgeben man möge es doch bitte installieren. Mal gucken wie das geht Shell-Scripte sind nicht so meine Spezialität bei einem C++ Programm täte ich mich leichter.

----------

## franzf

 *alexander_ro wrote:*   

> DIe zwei:
> 
> ```
> 
> eix --installed --exact dhcp
> ...

 

```
❯ eix --installed --exact dhcp

Kein Treffer

❯ echo $?                     

1

❯ eix --installed --exact awesome

[I] x11-wm/awesome

     Verfügbare Versionen:   3.4.15 (~)3.5.6-r1 3.5.6-r2 (~)3.5.7 (~)3.5.8 (~)3.5.9 (**)9999[1] {dbus doc gnome ELIBC="FreeBSD"}

     Installierte Versionen: 9999[1](14:37:26 08.06.2016)(dbus doc -gnome ELIBC="-FreeBSD")

     Startseite:             http://awesome.naquadah.org/

     Beschreibung:           A dynamic floating and tiling window manager

[1] "ff2000" /var/repositories/ff2000

❯ echo $?                        

0
```

@musv: Ich verwende auch -Ie allerdings ist das I immer so ne Sache... Je nach Font kann man das auch für ein kleines l oder eine 1 halten, deshalb hab ich lieber die langen Optionen geschrieben  :Wink: 

----------

## alexander_ro

Ja stimmt $? daran hatte ich nicht mehr gedacht. Ich hätte doch ein C++ Programm machen sollen da kenne ich mich besser aus. Aber ich habe mir ja unbedingt ein Shell-Script eingebildet ...

Das mit den ausgeschriebenen Optionen finde ich gerade im Forum praktisch man frägt ja nach etwas das man nicht kennt und muss dann nicht die Optionen erst in der Manpage suchen und mit den Zeichen die man leicht verwechselt gibts auch keine Probleme da hast Du schon recht.

Ich habe die Prüfung ob alle Pakete da sind die gebraucht werden jetzt so gemacht. Vielleicht nicht schön aber es geht ...  :Smile: 

```

  PaketFehlt=0

  eix --installed --exact --quiet dhcp

  if [ $? == 1 ]

  then

    PaketFehlt=1

    echo "Bitte das Paket "dhcp" installieren: emerge dhcp"

  fi

  eix --installed --exact --quiet iptables

  if [ $? == 1 ]

  then

    PaketFehlt=1

    echo "Bitte das Paket "iptables" installieren: emerge iptables"

  fi

  eix --installed --exact --quiet wpa_supplicant

  if [ $? == 1 ]

  then

    PaketFehlt=1

    echo "Bitte das Paket "wpa_supplicant" installieren: emerge wpa_supplicant"

  fi

  if [ $PaketFehlt == 1 ]

  then

    exit

  fi

```

Danke für eure Hilfe

----------

## 3PO

```
qlist -IC dhcp
```

----------

## alexander_ro

Das liefert bei mir dieses Ergebnis:

```

alien alex # qlist -IC dhcp

net-misc/dhcp

net-misc/dhcpcd

```

Edit: So vielleicht

```

qlist -IeC dhcp

```

----------

## 3PO

```
CHECK="dhcpcd"

[ !  "$(qlist -ICe $CHECK)" ] && echo "$CHECK is not installed"
```

----------

## alexander_ro

Sieht nach höherer Kryptografie aus ...  :Wink: 

So könnte man das dann in eine Funktion packen die man dann nur noch mit Parameter aufruft. Es fehlt nur noch der Merker damit man nach allen Prüfungen entscheiden kann ob man das Script wegen Fehlenden Paketen beenden muss oder nicht. Ich weiß jetzt aber nicht wie man bei Deiner Version noch den Wert des Merkers setzt.

Edit:

Ich hätte da zwar ein bisschen anderes Thema aber auch Shell Problem. Ich habe zwar die Lösung zusammen gefunden bekomme aber das Ergebnis nicht in eine Shell Variable. Wäre fein wenn Ihr da einen Tipp hättet wie das geht.

```

echo "obase=16; (${RANDOM} % 256)" | bc

```

----------

## 3PO

```
#!/bin/bash

Z="0"

for I in dhcp iptables wpa_supplicant ; do

  if [ !  "$(qlist -ICe $I)" ] ; then

    echo "$I is not installed"

    Z=$(($Z+1))

  fi   

done

if [ "$Z" -gt 0 ] ; then

  echo "$Z packages not installed"

  exit

fi
```

----------

## alexander_ro

Also wenn man mehr als ein Kommando ausführen will muss man dann einen "if" benutzen. Hab ich das jetzt richtig verstanden?

----------

## 3PO

Nö, es geht auch:

```
CHECK="dhcpcd" 

[ !  "$(qlist -ICe $CHECK)" ] && echo "$CHECK is not installed && exit"
```

Sieht halt doof aus.

----------

## alexander_ro

Macht auch bisschen was anderes ich wollte ja erst alle Pakete prüfen und dann das Script beenden wenn eins oder mehrere fehlen.

Damit man das Ding nicht drei mal Starten muss bis man weiß was noch fehlt.

Stimmt schon das mit den "if" und der Schleife sieht besser aus in dem Fall.

----------

## alexander_ro

Ist hübscher und auch leichter in anderen Scripten wieder zu verwenden. Danke für Deine Hilfe ...  :Smile: 

```

  PaketabhaengigkeitenPruefen ()

  {

    PaketListe=$1

    Z="0"

    for I in $PaketListe ; do

    if [ !  "$(qlist -ICe $I)" ] ; then

      echo "Bitte das Paket \"$I\" installieren: emerge --ask $I"

      Z=$(($Z+1))

    fi

    done

    if [ "$Z" -gt 0 ] ; then

      echo "$Z Pakete nicht installiert"

    exit

    fi

    echo "benötigte Gentoo Pakete installiert: check"

  }

  PaketabhaengigkeitenPruefen "dhcp iptables wpa_supplicant"

```

----------

## mv

Nochmal 'ne Alternative mit eix:

```
early_exit=:

for need in dhcp iptables wpa_supplicant

do eix -Ieq $need || { early_exit=exit

  echo "Bitte das Paket \"$need\" installieren: emerge $need" >&2

}

done

$early_exit 1
```

Wobei allerdings eix aus mehreren Gründen hier ungeeignet ist, die auch in der eix manpage bei "--installed" aufgelistet sind:Der Benutzer muss es installiert haben. (Das steht natürlich nicht in der manpage)Es muss eix-update aktuell genug aufgerufen worden seinEs gibt Ärger, wenn die Pakete einmal aus dem Gentoo-Baum verschwinden Mit qlist umgegeht man einige dieser Probleme, aber auch das ist nicht der "Unix way". Die richtige Lösung wäre so etwas: 

```
Die() {

  printf '%s' "$@"

  exit 1

}

command -v dhcpcd >/dev/null 2>&1 || Die 'dhcpcd ist nicht im PATH.' \

  'Bitte ggf. PATH korrigieren oder mit emerge -1 dhcpcd nachinstallieren.'
```

Das funktioniert dann auch auf anderen Systemen oder wenn der Benutzer dhcpcd nur lokal (etwa mit prefix-portage) installiert hat. Statt dem "exit" in "Die" kann man natürlich auch eine entsprechende Variable setzen. Eine Schleife ist wohl nicht möglich, da Paketnamen und zu testendes Kommando (oder ggf. zu testendes File - je nachdem, was Dein Script braucht) i.a. natürlich nicht identisch sind. Bei vielen Paketen kann man sicher mit einer Liste arbeiten, aber für 3-4 Tests lohnt sich das nicht.

----------

## alexander_ro

Danke für die weitere Version Interessant zu sehen was da so alles möglich ist. Die Version von 3PO ist zwar länger aber zumindest ich verstehe die schneller als die von Dir (mv).

Es muss jetzt nicht der Unix Weg sein ... der Gentoo Weg reicht mir. Da bin ich der Meinung das kann man am vorhanden sein des Pakets testen. Das Script soll dann auch noch die Kernel-Optionen prüfen und Vorschläge für die Konfiguration der Netzwerkdienste machen. Ich benutze derzeit kein andere Distribution. Um es wirklich Distributions unabhängig zu bauen müsste man auch die Verschiedenen Paketverwaltungen und Implementierungen der Netzwerkdienste berücksichtigen das macht viel Arbeit.

----------

