Verifica se un pacchetto è installato in APT


10

Voglio un metodo di script di shell per testare / segnalare se è installato un pacchetto. Non ho bisogno di dettagli, solo un ritorno booleano per impostare il flusso logico. Ho visto Trova se un pacchetto è installato , ma dpkgrestituisce un output complesso e il suo formato cambia a seconda che il pacchetto sia nel repository Debian o in un PPA Ubuntu.

Ho scoperto che apt-cachefa un ottimo lavoro e ho trovato questo metodo:

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

Qualcuno conosce un modo più semplice o più diretto?

Risposte:


12

dpkg-query come nel tuo post collegato sembra essere lo strumento più corretto per il lavoro, tranne usare ad esempio le librerie Python disponibili per legare direttamente al sistema APT in un tale contesto di scripting.

Con dpkg-query:

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

Restituirà true (stato di uscita 0nello script di shell) se il pacchetto è installato, falso (stato di uscita 1) in caso contrario.

  • -Wsignifica "Mostra" ( dpkg-querydeve avere un'azione richiesta).
  • -f cambia il formato dell'output.
  • db:Status-abbrev è la forma abbreviata dello stato del pacchetto.
  • 2>/dev/nullsilenzia dpkg-queryse viene fornito un nome pacchetto non valido. Come questo dovrebbe essere gestito potrebbe essere un problema caso per caso.
  • grep -q restituisce vero se c'è una corrispondenza, falso altrimenti.

Se viene usato spesso, potrebbe essere una semplice funzione:

#!/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

o semplicemente

#!/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

Sebbene questo sia senza dubbio corretto, trovo che di dpkg-query -l "$package" | grep -q ^.isolito sia sufficiente (e più facile da ricordare).
phogg,

1
@phogg: Sì, dipende dal fatto che debba vivere in uno script o meno. Inoltre, l' dpkg-query -loutput non è impostato su pietra poiché è solo una modalità di presentazione dell'utente, quindi se la presentazione cambia forse un tale script si spezzerebbe.
Daniel Andersson,

@ Daniel. Mi piace l'approccio del codice di ritorno. Si prega di vedere la mia risposta con i dettagli nel codice.
Tahoar,

Su 10.04 l'opzione di formato db: Status-abbrev non sembra esistere - ho usato: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'con lo stesso effetto.
scottynomad,

1

Ho testato i suggerimenti di Daniel su tre pacchetti con questi risultati:

  1. Pacchetto repository Debian nativo non installato:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. Pacchetto PPA registrato su host e installato:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. Pacchetto PPA registrato sull'host ma non installato:

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

Anche se mi piace l'approccio, sembra che non posso fidarmi del codice di ritorno con i pacchetti PPA. A parte questo, penso che continuerò ad analizzare il ritorno del apt-cache policycomando.


Bene, i tuoi esempi di codice non sono quello che ho detto che dovresti fare, ma immagino che ti sia appena sfuggita la grepparte nel tuo incolla. Non riesco davvero a riprodurre il tuo problema, ma potrebbe essere perché gli esempi di codice sono attualmente incompleti, quindi risolvilo. Gestisci Debian o Ubuntu?
Daniel Andersson,

Sto eseguendo Ubuntu 10.04 (i PPA non sono supportati direttamente su Debian?). Il mio codice ha rilasciato grep perché 1) il comando dkpg-query non scrive nulla su stdout e grep genera sempre un codice di ritorno. Il codice di ritorno dpkg-query è 0 se installato.
Tahoar,

2
1. Non taggare il tuo post "Debian" allora. 2. Non credo che tu abbia capito la parte grepgiocata nel comando, quindi l'hai spogliata e ora dici che non funziona? grep -qfornisce il codice di ritorno 1se non corrisponde, ovvero se il programma non è installato o non è disponibile o 0se il programma è installato. L'ho spiegato nel mio post.
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, la domanda non riguarda il controllo delle dipendenze. Inoltre, spiega cosa stanno facendo le parti del comando: altrimenti le altre persone non possono vedere cosa sta succedendo.
Daniel Andersson,

DEPS=$(echo {dialog,sqlite3,openssh-client})può essere equivalentemente scritto come solo DEPS="dialog sqlite3 openssh-client".
Daniel Andersson,

1

Mi piace la risposta di Daniel Andersson, ma non ha funzionato per me. Sono su Ubuntu 12.04.

Dalla pagina man di dpkg , db:Status-abbrevfunziona solo con dpkg 1.16.2+:

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

La mia soluzione era usare il comportamento legacy, solo il Statusformatter:

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

uscite

install ok installed 

Immagino che questa sia stata l'ispirazione per "ii" in altre rappresentazioni.

Quindi, per adattare completamente la risposta di Daniel Andersson al lavoro sulla versione precedente di dpkg, e quindi sulle distribuzioni Ubuntu precedenti:

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

Ritorna:

  • 0 - pacchetto installato, o
  • 1 - il pacchetto NON è installato.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.