Prueba si un paquete está instalado en APT

10

Quiero un método de script de shell para probar / informar si hay un paquete instalado. No necesito detalles, solo retorno booleano para establecer el flujo lógico. Miré Buscar si hay un paquete instalado , pero dpkgdevuelve resultados complejos y su formato cambia dependiendo de si el paquete está en el repositorio de Debian o en un PPA de Ubuntu.

Descubrí que apt-cachehace un trabajo bastante bueno y se me ocurrió este método:

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

¿Alguien sabe de una manera más simple o más directa?

tahoar
fuente

Respuestas:

12

dpkg-query como en su publicación vinculada parece ser la herramienta más correcta para el trabajo, excepto el uso, por ejemplo, de las bibliotecas de Python disponibles para enlazar directamente con el sistema APT en dicho contexto de secuencias de comandos.

Con dpkg-query:

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

Devolverá verdadero (estado de salida 0en el script de shell) si el paquete está instalado, falso (estado de salida 1) de lo contrario.

  • -Wsignifica "Mostrar" ( dpkg-querydebe tener una acción solicitada).
  • -f cambia el formato de la salida.
  • db:Status-abbrev es la forma abreviada del estado del paquete.
  • 2>/dev/nullsilencia dpkg-querysi se da un nombre de paquete no válido. Cómo se debe manejar esto podría ser un problema de caso a caso.
  • grep -q devuelve verdadero si hay una coincidencia, falso de lo contrario.

Si se usa con frecuencia, podría hacerse una función simple:

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

#!/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
fuente
Si bien esto es sin duda correcto, creo que dpkg-query -l "$package" | grep -q ^.isuele ser suficiente (y más fácil de recordar).
phogg
1
@phogg: Sí, depende de si se supone que debe vivir en un script o no. Además, la dpkg-query -lsalida no se establece en piedra ya que es solo un modo de presentación del usuario, por lo que si la presentación cambia, tal secuencia de comandos podría romperse.
Daniel Andersson
@Daniel. Me gusta el enfoque del código de retorno. Por favor vea mi respuesta con detalles en el código.
tahoar
En 10.04, la opción de formato db: Status-abbrev no parece existir. Utilicé: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'para el mismo efecto.
scottynomad
1

Probé las sugerencias de Daniel en tres paquetes con estos resultados:

  1. Paquete de repositorio nativo de Debian no instalado:

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

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. Paquete PPA registrado en el host pero no 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.
    

Aunque me gusta el enfoque, parece que no puedo confiar en el código de retorno con los paquetes PPA. Aparte de eso, creo que seguiré analizando el regreso del apt-cache policycomando.

tahoar
fuente
Bueno, sus ejemplos de código no son lo que dije que debería hacer, pero supongo que se ha perdido la grepparte de su pegado. Realmente no puedo reproducir su problema, pero eso podría deberse a que los ejemplos de código están actualmente incompletos, así que solucione eso. ¿Ejecutas Debian o Ubuntu?
Daniel Andersson
Estoy ejecutando Ubuntu 10.04 (¿son compatibles los PPA sin Debian directo?). Mi código eliminó su grep porque 1) el comando dkpg-query no escribe nada en stdout y grep siempre arroja un código de retorno. El código de retorno dpkg-query es 0 si está instalado.
tahoar
2
1. No etiquete su publicación "Debian" entonces. 2. No creo que hayas entendido el papel grepdesempeñado en el comando, ¿así que lo eliminaste y ahora dices que no funciona? grep -qda el código de retorno 1si no coincide, es decir, el programa no está instalado o no está disponible, o 0si el programa está instalado. Lo expliqué en mi publicación.
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
fuente
-1, la pregunta no es sobre la comprobación de dependencias. Además, explique qué están haciendo las partes del comando: de lo contrario, otras personas no pueden ver lo que está sucediendo.
Daniel Andersson
DEPS=$(echo {dialog,sqlite3,openssh-client})se puede escribir de manera equivalente como justo DEPS="dialog sqlite3 openssh-client".
Daniel Andersson
1

Me gusta la respuesta de Daniel Andersson, pero no funcionó para mí. Estoy en Ubuntu 12.04.

Desde la página de manual de dpkg , db:Status-abbrevsolo funciona en dpkg 1.16.2+:

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

Mi solución fue usar el comportamiento heredado, solo el Statusformateador:

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

salidas

install ok installed 

Supongo que esto fue la inspiración para "ii" en otras representaciones.

Entonces, para adaptar completamente la respuesta de Daniel Andersson para trabajar en una versión anterior de dpkg y, por lo tanto, distribuciones de Ubuntu más antiguas:

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

Devoluciones:

  • 0: el paquete está instalado o
  • 1 - el paquete NO está instalado.
Wilbur Whateley
fuente