apt-get update exit status

12,421

Solution 1

In your example apt-get update didn't exit with error, because it considered the problems as warnings, not as fatally bad. If there's a really fatal error, then it would exit with non-zero status.

One way to recognize anomalies is by checking for these patterns in stderr:

  • Lines starting with W: are warnings
  • Lines starting with E: are errors

You could use something like this to emulate a failure in case the above patterns match, or the exit code of apt-get update itself is non-zero:

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

Note the ! in the if. It's because the grep exits with success if the pattern was matched, that is if there were errors. When there are no errors the grep itself will fail. So the if condition is to negate the exit code of the grep.

Solution 2

Use this apt option to turn those warnings into errors:

apt-get update -o APT::Update::Error-Mode=any

You can also set that in conf files if you wish.

Solution 3

I was faced with the same issue, and I would like to propose another solution that relies on tee (like @user4122451's solution), but doesn't create a temporary file, and also fails if sudo apt-get update returns a non-zero exit code without outputting some W: or E: or Err: string:

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

Specifically, this solution relies on the set -o pipefail bash option (ensuring the pipeline returns the value of the rightmost command to exit with a non-zero status, otherwise zero) and uses an additional numbered file descriptor (see also this SO answer).

If you need not make the pipefail option local, you could write just as well:

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

Solution 4

If you want apt-get's out/err to not get eaten (e.g. if writing to a log file), this might be a simpler alternative:

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

It would be nice if this didn't leave a new file lying around to remove later, but if we, say, process substitute the grep into the tee output it seems to get more difficult to get the exit code.

Share:
12,421

Related videos on Youtube

Pol Hallen
Author by

Pol Hallen

Updated on September 18, 2022

Comments

  • Pol Hallen
    Pol Hallen 4 months

    How check the status of 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
    

    Here there's an error with fetch of security updates but exit status is 0

    My goal is a script to check if apt-get update runs correctly.

  • ErikMD
    ErikMD about 2 years
    The issue is that apt-get update won't fail if it just encounters a network issue: sudo apt-get update; echo $? yields 0, albeit prints W: Some index files failed to download. They have been ignored, or old ones used instead; hence the use of grep in all proposed solutions (the accepted one with a mere grep, @user4122451's solution with tee and a temporary file, and mine with a tee, no temporary file, and a custom file descriptor).