estado de salida de apt-get update

8

¿Cómo verificar el estado de apt-get update?

$ apt-get update ; echo "status is: $?"

Err http://security.debian.org stable/updates Release.gpg
Could not resolve 'security.debian.org'
Hit http://192.168.1.100 stable Release.gpg
Hit http://192.168.1.100 stable Release
Hit http://192.168.1.100 stable/main i386 Packages
Hit http://192.168.1.100 stable/contrib i386 Packages
Hit http://192.168.1.100 stable/non-free i386 Packages
Ign http://192.168.1.100 stable/contrib Translation-en
Ign http://192.168.1.100 stable/main Translation-en
Ign http://192.168.1.100 stable/non-free Translation-en
Reading package lists... Done
W: Failed to fetch http://security.debian.org/dists/stable/updates/Release.gpg  Could not resolve 'security.debian.org'
W: Some index files failed to download. They have been ignored, or old ones used instead.

status is: 0

Aquí hay un error con la búsqueda de actualizaciones de seguridad pero el estado de salida es 0

Mi objetivo es un script para verificar si apt-get update se ejecuta correctamente.

Pol Hallen
fuente

Respuestas:

6

En su ejemplo apt-get update, no salió con error, porque consideraba los problemas como advertencias, no como fatalmente malas. Si hay un error realmente fatal, saldría con un estado distinto de cero.

Una forma de reconocer anomalías es verificando estos patrones en stderr:

  • Las líneas que comienzan con W:son advertencias
  • Las líneas que comienzan con E:son errores

Podría usar algo como esto para emular una falla en caso de que los patrones anteriores coincidan, o el código de salida en apt-get updatesí mismo no sea cero:

if ! { sudo apt-get update 2>&1 || echo E: update failed; } | grep -q '^[WE]:'; then
    echo success
else
    echo failure
fi

Tenga !en cuenta el en el if. Es porque las grepsalidas con éxito si el patrón coincide, es decir, si hubo errores. Cuando no hay errores, el grepmismo fallará. Entonces, la ifcondición es negar el código de salida de grep.

janos
fuente
1

Si desea que apt-get's out / err no se coman (por ejemplo, si escribe en un archivo de registro), esta podría ser una alternativa más simple:

sudo apt-get update 2>&1 | tee /tmp/apt.err && ! grep -q '^[WE]' /tmp/apt.err

Sería bueno si esto no dejara un nuevo archivo para eliminarlo más tarde, pero si, por ejemplo, sustituimos el grep en la salida del tee, parece que es más difícil obtener el código de salida.

user4122451
fuente
1

Me enfrenté al mismo problema, y ​​me gustaría proponer otra solución que se base en tee(como la solución de @ user4122451), pero que no cree un archivo temporal, y que también falle si sudo apt-get updatedevuelve un código de salida distinto de cero sin generar alguno W:o E:o Err:cadena:

exec {fd}>&2 # copy stderr to some unused fd
bash -o pipefail -c "sudo apt-get update -y -q 2>&1 | tee /dev/fd/$fd | ( ! grep -q -e '^Err:' -e '^[WE]:' )"
result=$?
exec {fd}>&- # close file descriptor

Específicamente, esta solución se basa en la set -o pipefailopción bash (asegurando que la tubería devuelva el valor del comando más a la derecha para salir con un estado distinto de cero, de lo contrario cero) y utiliza un descriptor de archivo numerado adicional (consulte también esta respuesta SO ).

Si no necesita hacer que la pipefailopción sea local, también podría escribir:

set -o pipefail
exec {fd}>&2 # copy stderr to some unused fd
sudo apt-get update -y -q 2>&1 | tee /dev/fd/$fd | ( ! grep -q -e '^Err:' -e '^[WE]:' )
result=$?
exec {fd}>&- # close file descriptor
ErikMD
fuente