apt-get update exit status

8

Как проверить статус 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

Здесь есть ошибка при получении обновлений безопасности, но статус выхода равен 0

Моя цель - скрипт для проверки правильности выполнения обновления apt-get.

Пол Халлен
источник

Ответы:

6

В вашем примере apt-get updateне завершился с ошибкой, потому что рассматривал проблемы как предупреждения, а не как фатально плохие. Если есть действительно фатальная ошибка, она завершится с ненулевым статусом.

Одним из способов распознавания аномалий является проверка этих шаблонов в stderr:

  • Строки, начинающиеся с W:предупреждений
  • Строки, начинающиеся с E:ошибок

Вы можете использовать что-то вроде этого, чтобы эмулировать сбой в случае совпадения вышеуказанных шаблонов, или если сам код выхода apt-get updateне равен нулю:

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

Обратите внимание на !в if. Это потому, что grepвыходы с успехом, если шаблон был сопоставлен, то есть если были ошибки. Когда ошибок нет, grepсамо произойдет сбой. Таким образом, ifусловие - отменить код выхода grep.

Янош
источник
1

Если вы хотите, чтобы apt-get out / err не был съеден (например, при записи в файл журнала), это может быть более простой альтернативой:

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

Было бы неплохо, если бы это не оставило новый файл, который можно было бы удалить позже, но если мы, скажем, обработаем замену grep в выводе tee, то будет сложнее получить код выхода.

user4122451
источник
1

Я столкнулся с той же проблемой, и я хотел бы предложить другое решение, которое опирается tee(например, на решение @ user4122451), но не создает временный файл, а также дает сбой, если sudo apt-get updateвозвращает ненулевой код выхода без вывода некоторых W:или E:или Err:строка:

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

В частности, это решение опирается на set -o pipefailопцию bash (обеспечение того, что конвейер возвращает значение самой правой команды для выхода с ненулевым состоянием, в противном случае - ноль) и использует дополнительный номерной дескриптор файла (см. Также этот ответ SO ).

Если вам не нужно делать эту pipefailопцию локальной, вы также можете написать:

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
источник