apt-get update exit status

8

Comment vérifier le statut 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

Ici, il y a une erreur avec la récupération des mises à jour de sécurité, mais l'état de sortie est 0

Mon objectif est un script pour vérifier si la mise à jour apt-get fonctionne correctement.

Pol Hallen
la source

Réponses:

6

Dans votre exemple, il apt-get updaten'est pas sorti avec erreur, car il considérait les problèmes comme des avertissements, pas comme fatalement mauvais. S'il y a une erreur vraiment fatale, elle se terminerait avec un état différent de zéro.

Une façon de reconnaître les anomalies consiste à vérifier ces modèles dans stderr:

  • Les lignes commençant par W:sont des avertissements
  • Les lignes commençant par E:sont des erreurs

Vous pouvez utiliser quelque chose comme ceci pour émuler un échec au cas où les modèles ci-dessus correspondent, ou si le code de sortie apt-get updatelui-même n'est pas nul:

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

Notez le !dans le if. C'est parce que les grepsorties sont réussies si le motif est apparié, c'est-à-dire s'il y a des erreurs. Lorsqu'il n'y a aucune erreur, le greplui - même échouera. La ifcondition est donc de nier le code de sortie du grep.

janos
la source
1

Si vous voulez que apt-get out / err ne soit pas mangé (par exemple si vous écrivez dans un fichier journal), cela pourrait être une alternative plus simple:

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

Ce serait bien si cela ne laissait pas un nouveau fichier traîner pour le supprimer plus tard, mais si nous disons que le processus substitue le grep à la sortie du tee, il semble plus difficile d'obtenir le code de sortie.

user4122451
la source
1

J'étais confronté au même problème, et je voudrais proposer une autre solution qui s'appuie sur tee(comme la solution de @ user4122451), mais qui ne crée pas de fichier temporaire et échoue également si sudo apt-get updaterenvoie un code de sortie non nul sans en sortir W:ou E:ou Err:chaîne:

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

Plus précisément, cette solution repose sur l' set -o pipefailoption bash (garantissant que le pipeline renvoie la valeur de la commande la plus à droite pour quitter avec un état non nul, sinon zéro) et utilise un descripteur de fichier numéroté supplémentaire (voir également cette réponse SO ).

Si vous n'avez pas besoin de rendre l' pipefailoption locale, vous pouvez tout aussi bien écrire:

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
la source