apt-get update exit status

8

Wie überprüfe ich den Status von 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

Hier ist ein Fehler beim Abrufen von Sicherheitsupdates aufgetreten, aber der Beendigungsstatus ist 0

Mein Ziel ist ein Skript, um zu überprüfen, ob das apt-get-Update korrekt ausgeführt wird.

Pol Hallen
quelle

Antworten:

6

In Ihrem Beispiel apt-get updatewurde nicht mit Fehler beendet, da die Probleme als Warnungen und nicht als tödlich schlimm angesehen wurden. Wenn es einen wirklich schwerwiegenden Fehler gibt, wird er mit einem Status ungleich Null beendet.

Eine Möglichkeit, Anomalien zu erkennen, besteht darin, nach folgenden Mustern zu suchen stderr:

  • Zeilen, die mit beginnen, W:sind Warnungen
  • Zeilen, die mit beginnen, E:sind Fehler

Sie können so etwas verwenden, um einen Fehler zu emulieren, falls die obigen Muster übereinstimmen oder der Exit-Code apt-get updateselbst nicht Null ist:

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

Beachten Sie die !in der if. grepDies liegt daran, dass die Exits mit Erfolg beendet werden, wenn das Muster übereinstimmt, dh wenn Fehler aufgetreten sind. Wenn keine Fehler grepvorliegen, schlägt der Fehler selbst fehl. Die ifBedingung ist also, den Exit-Code des zu negieren grep.

Janos
quelle
1

Wenn Sie möchten, dass apt-get's out / err nicht gegessen wird (z. B. beim Schreiben in eine Protokolldatei), ist dies möglicherweise eine einfachere Alternative:

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

Es wäre schön, wenn dadurch keine neue Datei herumliegen würde, um sie später zu entfernen, aber wenn wir beispielsweise den grep in der Tee-Ausgabe ersetzen, scheint es schwieriger zu werden, den Exit-Code zu erhalten.

user4122451
quelle
1

Ich war mit dem gleichen Problem konfrontiert und möchte eine andere Lösung vorschlagen, die sich darauf stützt tee(wie die Lösung von @ user4122451), aber keine temporäre Datei erstellt und auch fehlschlägt, wenn sudo apt-get updateein Exit-Code ungleich Null zurückgegeben wird, ohne einen W:oder auszugeben E:oder Err:Zeichenfolge:

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

Insbesondere basiert diese Lösung auf der set -o pipefailBash-Option (um sicherzustellen, dass die Pipeline den Wert des Befehls ganz rechts zurückgibt, um mit einem Status ungleich Null zu beenden, andernfalls Null) und verwendet einen zusätzlichen nummerierten Dateideskriptor (siehe auch diese SO-Antwort ).

Wenn Sie die pipefailOption nicht lokal machen müssen, können Sie genauso gut schreiben:

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
quelle