apt-get aggiorna lo stato di uscita


8

Come controllare lo stato di 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

Qui c'è un errore con il recupero degli aggiornamenti di sicurezza ma lo stato di uscita è 0

Il mio obiettivo è uno script per verificare se l'aggiornamento apt-get funziona correttamente.

Risposte:


6

Nel tuo esempio apt-get updatenon è uscito con errore, perché ha considerato i problemi come avvertimenti, non fatalmente gravi. Se c'è un errore davvero fatale, allora uscirà con uno stato diverso da zero.

Un modo per riconoscere le anomalie è controllando questi schemi in stderr:

  • Le righe che iniziano con W:sono avvertenze
  • Le righe che iniziano con E:sono errori

È possibile utilizzare qualcosa del genere per emulare un errore nel caso in cui i modelli sopra riportati corrispondano o il codice di uscita apt-get updatestesso sia diverso da zero:

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

Nota !in if. È perché le grepuscite hanno esito positivo se il modello è stato abbinato, cioè se ci sono stati errori. Quando non ci sono errori, lo grepstesso fallirà. Quindi la ifcondizione è di annullare il codice di uscita di grep.


1

Se si desidera che apt-get's out / err non venga mangiato (ad esempio se si scrive in un file di registro), questa potrebbe essere un'alternativa più semplice:

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

Sarebbe bello se questo non lasciasse in giro un nuovo file da rimuovere in seguito, ma se, diciamo, elaboriamo il grep nell'output del tee, sembra essere più difficile ottenere il codice di uscita.


1

Ho dovuto affrontare lo stesso problema e vorrei proporre un'altra soluzione su cui fare affidamento tee(come la soluzione di @ user4122451), ma non crea un file temporaneo e fallisce anche se sudo apt-get updaterestituisce un codice di uscita diverso da zero senza emettere alcuni W:o E:o Err:stringa:

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

In particolare, questa soluzione si basa set -o pipefailsull'opzione bash (assicurandosi che la pipeline restituisca il valore del comando più a destra per uscire con uno stato diverso da zero, altrimenti zero) e utilizza un descrittore di file numerato aggiuntivo (vedere anche questa risposta SO ).

Se non è necessario rendere l' pipefailopzione locale, è possibile scrivere anche:

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