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 stable Release.gpg
Hit stable Release
Hit stable/main i386 Packages
Hit stable/contrib i386 Packages
Hit stable/non-free i386 Packages
Ign stable/contrib Translation-en
Ign stable/main Translation-en
Ign 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.

5 Answers 5


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.


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
    echo failure

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.


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.


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]:' )"
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]:' )
exec {fd}>&- # close file descriptor

You can use a special variable $? to check the exit status of your last command. You can also redirect the error output to the standard output first.

OUTPUT=`apt-get update 2>&1`

if [[ $? != 0 ]]; then
  echo "$OUTPUT"
  • 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).
    – ErikMD
    Nov 16, 2020 at 14:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .