status de saída da atualização do apt-get

8

Como verificar o status de 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

Aqui há um erro ao buscar atualizações de segurança, mas o status de saída é 0

Meu objetivo é um script para verificar se a atualização do apt-get é executada corretamente.

Pol Hallen
fonte

Respostas:

6

No seu exemplo apt-get updatenão saiu com erro, porque considerou os problemas como avisos, não como fatalmente ruins. Se houver um erro realmente fatal, ele sairá com status diferente de zero.

Uma maneira de reconhecer anomalias é verificar esses padrões em stderr:

  • Linhas começando com W:são avisos
  • Linhas começando com E:são erros

Você pode usar algo parecido com isto para emular uma falha, caso os padrões acima correspondam ou o código de saída apt-get updateseja diferente de zero:

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

Observe o !no if. É porque as grepsaídas com êxito se o padrão foi correspondido, isto é, se houve erros. Quando não há erros, o greppróprio falhará. Portanto, a ifcondição é negar o código de saída do grep.

janos
fonte
1

Se você deseja que o apt-get's out / err não seja comido (por exemplo, se estiver gravando em um arquivo de log), essa pode ser uma alternativa mais simples:

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

Seria bom se isso não deixasse um novo arquivo para ser removido mais tarde, mas se, digamos, processarmos o grep na saída tee, ficará mais difícil obter o código de saída.

user4122451
fonte
1

Fui confrontado com o mesmo problema e gostaria de propor outra solução que se baseia tee(como a solução do @ user4122451), mas não cria um arquivo temporário e também falha se sudo apt-get updateretornar um código de saída diferente de zero sem gerar alguma W:ou E:ou 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

Especificamente, esta solução conta com a set -o pipefailopção bash (garantindo que o pipeline retorne o valor do comando mais à direita para sair com um status diferente de zero, caso contrário, zero) e use um descritor de arquivo numerado adicional (consulte também esta resposta do SO ).

Se você não precisar tornar a pipefailopção local, você também pode escrever:

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
fonte