Sprawdź, czy pakiet jest zainstalowany w APT

10

Chcę, aby metoda skryptów powłoki testowała / raportowała, czy pakiet jest zainstalowany. Nie potrzebuję szczegółów, tylko powrót logiczny, aby ustawić przepływ logiki. Spojrzałem na Znajdź, czy pakiet jest zainstalowany , ale dpkgzwraca złożone dane wyjściowe, a jego format zmienia się w zależności od tego, czy pakiet znajduje się w repozytorium Debiana, czy w Ubuntu PPA.

Odkryłem, że apt-cacherobi to całkiem niezłą robotę i wymyśliłem tę metodę:

is_installed=0
test_installed=( `apt-cache policy package-name | grep "Installed:" ` )
[ ! "${test_installed[1]}" == "(none)" ] && is_installed=1

Czy ktoś zna prostszy lub bardziej bezpośredni sposób?

tahoar
źródło

Odpowiedzi:

12

dpkg-query jak w twoim łączonym poście wydaje się być najbardziej odpowiednim narzędziem dla zadania, z wyjątkiem użycia np. dostępnych bibliotek Pythona do bezpośredniego łączenia się z systemem APT w takim kontekście skryptowym.

Z dpkg-query:

dpkg-query -Wf'${db:Status-abbrev}' package-name 2>/dev/null | grep -q '^i'

Zwraca true (kod wyjścia 0w skrypcie powłoki), jeśli pakiet jest zainstalowany, false (kod wyjścia 1) w przeciwnym razie.

  • -Woznacza „Pokaż” ( dpkg-querymusi mieć wymagane działanie).
  • -f zmienia format wyniku.
  • db:Status-abbrev jest krótką formą statusu paczki.
  • 2>/dev/nullwycisza się, dpkg-queryjeśli podana zostanie niepoprawna nazwa pakietu. Sposób, w jaki należy to rozwiązać, może być kwestią indywidualną.
  • grep -q zwraca true, jeśli istnieje dopasowanie, false w przeciwnym razie.

Jeśli jest często używany, można go uczynić prostą funkcją:

#!/bin/sh
debInst() {
    dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
}

if debInst "$1"; then
    printf 'Why yes, the package %s _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package %s is not currently installed.\n' "$1"
fi

lub po prostu

#!/bin/sh
if dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'; then
    printf 'Why yes, the package "%s" _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package "%s" is not currently installed.\n' "$1"
fi
Daniel Andersson
źródło
Chociaż jest to niewątpliwie poprawne, uważam, że dpkg-query -l "$package" | grep -q ^.ijest to zwykle wystarczające (i łatwiejsze do zapamiętania).
phogg
1
@phogg: Tak, zależy od tego, czy ma żyć w skrypcie, czy nie. Ponadto dpkg-query -lwynik nie jest ustawiony, ponieważ jest to tylko tryb prezentacji użytkownika, więc jeśli prezentacja się zmieni, być może taki skrypt się zepsuje.
Daniel Andersson
@Daniel. Lubię podejście do kodu powrotu. Proszę zobaczyć moją odpowiedź ze szczegółami w kodzie.
tahoar
10.04 opcja formatu db: Status-skrót nie istnieje - użyłem: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'z tym samym skutkiem.
scottynomad,
1

Testowałem sugestie Daniela dotyczące trzech pakietów z następującymi wynikami:

  1. Natywny pakiet repozytorium Debiana nie został zainstalowany:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. Pakiet PPA zarejestrowany na hoście i zainstalowany:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. Pakiet PPA zarejestrowany na hoście, ale nie zainstalowany:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' 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.
    

Chociaż podoba mi się to podejście, wydaje się, że nie mogę ufać kodowi zwrotnemu z pakietami PPA. Krótko mówiąc, myślę, że pozostanę przy analizie powrotu apt-cache policypolecenia.

tahoar
źródło
Cóż, twoje przykłady kodu nie są tym, co powiedziałem, że powinieneś zrobić, ale myślę, że właśnie przegapiłeś grepczęść swojego wklejania. Naprawdę nie mogę odtworzyć Twojego problemu, ale może to być spowodowane tym, że przykłady kodu są obecnie niekompletne, więc napraw to. Czy korzystasz z Debiana lub Ubuntu?
Daniel Andersson
Używam Ubuntu 10.04 (czy PPA nie obsługuje prostej wersji Debiana?). Mój kod upuścił twój grep, ponieważ 1) polecenie dkpg-query nie zapisuje nic na standardowe wyjście, a grep zawsze rzuca kod powrotu. Kod powrotu zapytania dpkg wynosi 0, jeśli jest zainstalowany.
tahoar
2
1. Nie oznaczaj więc swojego postu „Debian”. 2. Nie sądzę, abyś zrozumiał rolę grepodgrywaną w poleceniu, więc ją rozebrałeś, a teraz mówisz, że to nie działa? grep -qpodaje kod powrotu, 1jeśli nie pasuje, tj. program nie jest zainstalowany lub niedostępny, lub 0jeśli program jest zainstalowany. Wyjaśniłem to w moim poście.
Daniel Andersson
1
#!/bin/bash

# Check for dependencies 
check_deps () {
DEPS=$(echo {dialog,sqlite3,openssh-client})
for i in $DEPS ; do
    dpkg-query -W -f='${Package}\n' | grep ^$i$ > /dev/null
    if [ $? != 0 ] ; then
        echo "Installing deps ..."
        aptitude install $i -y > /dev/null
    fi
done  
}

# execute the check_deps function
check_deps
Diego Roberto Dos Santos
źródło
-1, pytanie nie dotyczy sprawdzania zależności. Wyjaśnij także, co robi część polecenia: w przeciwnym razie inni ludzie nie zobaczą, co się dzieje.
Daniel Andersson
DEPS=$(echo {dialog,sqlite3,openssh-client})można napisać równorzędnie jako sprawiedliwy DEPS="dialog sqlite3 openssh-client".
Daniel Andersson,
1

Podoba mi się odpowiedź Daniela Anderssona, ale dla mnie to nie zadziałało. Jestem na Ubuntu 12.04.

Od strony man dpkg , db:Status-abbrevdziała tylko w dpkg 1.16.2+:

          db:Status-Abbrev
                 It  contains the abbreviated package status, such as “ii”
                 (since dpkg 1.16.2).

Moim rozwiązaniem było użycie starszego zachowania, tylko Statusformatyzator:

dpkg-query -Wf'${Status}' {my_pkg_name}

wyjścia

install ok installed 

Zgaduję, że to była inspiracja dla „ii” w innych przedstawieniach.

Tak więc, aby całkowicie dostosować odpowiedź Daniela Anderssona do pracy nad starszą wersją dpkg, a tym samym starszymi dystrybucjami Ubuntu:

dpkg-query -Wf'${Status}' {your_pkg_name} 2>/dev/null | grep -q "install ok installed"

Zwroty:

  • 0 - pakiet jest zainstalowany, lub
  • 1 - pakiet NIE jest zainstalowany.
Wilbur Whateley
źródło