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?

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

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.


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

-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.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.