Teste se um pacote está instalado no APT

10

Eu quero um método de script de shell para testar / relatar se um pacote está instalado. Não preciso de detalhes, apenas retorno booleano para definir o fluxo lógico. Eu olhei para Localizar se um pacote está instalado , mas dpkgretorna uma saída complexa e seu formato muda dependendo se o pacote está no repositório Debian ou em um PPA do Ubuntu.

Descobri que apt-cachefaz um bom trabalho e criei este método:

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

Alguém conhece uma maneira mais simples ou direta?

tahoar
fonte

Respostas:

12

dpkg-query como em sua postagem vinculada, parece ser a ferramenta mais correta para o trabalho, exceto o uso, por exemplo, das bibliotecas Python disponíveis para vincular diretamente ao sistema APT em um contexto de script.

Com dpkg-query:

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

Retornará true (status de saída 0no script shell) se o pacote estiver instalado; false (status de saída 1) caso contrário.

  • -Wsignifica "Mostrar" ( dpkg-querydeve ter uma ação solicitada).
  • -f altera o formato da saída.
  • db:Status-abbrev é a forma abreviada do status do pacote.
  • 2>/dev/nullsilencia dpkg-queryse um nome de pacote inválido for fornecido. Como isso deve ser tratado pode ser um problema caso a caso.
  • grep -q retorna true se houver uma correspondência, false caso contrário.

Se for usado com frequência, pode ser feita uma função simples:

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

ou simplesmente

#!/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
fonte
Embora isso seja sem dúvida correto, acho que dpkg-query -l "$package" | grep -q ^.igeralmente é suficiente (e mais fácil de lembrar).
Phogg 22/05/12
1
@phogg: Sim, depende se é para viver em um script ou não. Além disso, a dpkg-query -lsaída não é definida, pois é apenas um modo de apresentação do usuário; portanto, se a apresentação mudar, talvez esse script seja interrompido.
Daniel Andersson
@Daniel. Eu gosto da abordagem do código de retorno. Por favor, veja minha resposta com detalhes no código.
Tahoar 23/05
No 10.04, a opção de formato db: Status-abbrev parece não existir - usei: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'para o mesmo efeito.
#
1

Testei as sugestões de Daniel em três pacotes com estes resultados:

  1. Pacote de repositório Debian nativo não instalado:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. Pacote PPA registrado no host e instalado:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. Pacote PPA registrado no host, mas não instalado:

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

Embora eu goste da abordagem, parece que não posso confiar no código de retorno com pacotes PPA. Além disso, acho que vou continuar analisando o retorno do apt-cache policycomando.

tahoar
fonte
Bem, seus exemplos de código não são o que eu disse que você deveria fazer, mas acho que você acabou de perder a grepparte do seu colar. Não consigo realmente reproduzir seu problema, mas isso pode ser porque os exemplos de código estão incompletos no momento, portanto, corrija-o. Você roda o Debian ou o Ubuntu?
Daniel Andersson #
Estou executando o Ubuntu 10.04 (os PPAs não suportam Debian direto?). Meu código eliminou o seu grep porque 1) o comando dkpg-query não grava nada no stdout e o grep sempre lança um código de retorno. O código de retorno do dpkg-query é 0 se instalado.
Tahoar 23/05
2
1. Não marque sua postagem como "Debian" então. 2. Eu não acho que você entendeu o papel grepdesempenhado no comando, então você o retirou e agora diz que não funciona? grep -qfornece código de retorno 1se não corresponder, ou seja, o programa não estiver instalado ou indisponível, ou 0se o programa estiver instalado. Eu expliquei isso no meu 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
Diego Roberto Dos Santos
fonte
-1, a questão não é sobre verificação de dependência. Além disso, explique o que as partes do comando estão fazendo: caso contrário, outras pessoas não poderão ver o que está acontecendo.
Daniel Andersson
DEPS=$(echo {dialog,sqlite3,openssh-client})pode ser equivalentemente escrito como justo DEPS="dialog sqlite3 openssh-client".
Daniel Andersson
1

Gosto da resposta de Daniel Andersson, mas não funcionou para mim. Estou no Ubuntu 12.04.

Na página do manual do dpkg , db:Status-abbrevfunciona apenas no dpkg 1.16.2+:

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

Minha solução foi usar o comportamento herdado, apenas o Statusformatador:

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

saídas

install ok installed 

Acho que essa foi a inspiração para "ii" em outras representações.

Portanto, para adaptar completamente a resposta de Daniel Andersson para trabalhar na versão mais antiga do dpkg e, portanto, nas distribuições mais antigas do Ubuntu:

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

Devoluções:

  • 0 - o pacote está instalado ou
  • 1 - pacote NÃO está instalado.
Wilbur Whateley
fonte