Scripts de Bash Shell: Aunque apt-get update falló, el estado de salida es 0, se escriben scripts de actualización automática utilizando el estado de salida

Scripts de Bash Shell: Aunque apt-get update falló, el estado de salida es 0, se escriben scripts de actualización automática utilizando el estado de salida

Estoy intentando escribir un script de actualización y actualización automática.

Quiero utilizar el estado de salida de la ejecución del comando,

pero incluso si el comando apt-get update falla, devuelve el estado de salida 0.

Entonces mi guión no puede lograr el propósito.

PREGUNTAS============

¿Por qué apt-get update devuelve 0? Sin embargo, quiero obtener otros números en lugar de 0 cuando falla el comando.

Y para que mi script logre el propósito, ¿cómo podría modificarlo?

======================

¡Gracias por su lectura!

Aquí está la parte de actualización de mi script;

#!/bin/bash -x 

### Variables
count=
command_result=""

### Main

echo "$(LC_TIME=en_US.UTF-8 date)" >> log_update

until [ "$count" = "10" ] || [ "$command_result" = "done" ]; do

    sudo apt-get update

    if [ "$?" = "0" ]; then
        echo "Update succeeds." >> ~/log_update
        command_result="done"
    fi

    count=$((count + 1)) 

done

if [ "$command" != "done" ]; then
    echo "Time Out: Update FAILED! Solve Problem." >> log_update
fi

Respuesta1

Para entender por qué aptor apt-getdevuelve 0, incluso cuando encuentra un error, primero debe saber que estos comandos también son un programa desarrollado por algún programador. Por lo tanto, los valores devueltos al terminal también los decide el desarrollador del programa.

El único caso en el que he visto que aptno funciona es cuando se ejecuta sin sudo
privilegios de superusuario. Aquí hay un fragmento de código cuando apt se ejecuta sin privilegios de superusuario:

mars@HP-Notebook:~/Desktop/Practice/cpp$ apt update
Reading package lists... Done
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
E: Unable to lock directory /var/lib/apt/lists/
W: Problem unlinking the file /var/cache/apt/pkgcache.bin - RemoveCaches (13: Permission denied)
W: Problem unlinking the file /var/cache/apt/srcpkgcache.bin - RemoveCaches (13: Permission denied)
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
100

Como puede ver, el código de salida no es 0. Por lo tanto, podemos concluir que el comando o programa no se ejecutó.
Tomemos otro caso, cuando no hay conexión a Internet:

mars@HP-Notebook:~/Desktop/Practice/cpp$ sudo apt update
Err:1 http://security.ubuntu.com/ubuntu bionic-security InRelease
  Could not resolve 'security.ubuntu.com'
Err:2 http://dl.google.com/linux/chrome/deb stable InRelease                                                   
  Could not resolve 'dl.google.com'
Err:3 http://in.archive.ubuntu.com/ubuntu bionic InRelease                                                     
  Could not resolve 'in.archive.ubuntu.com'
Err:4 https://download.sublimetext.com apt/stable/ InRelease                     
  Could not resolve 'download.sublimetext.com'
Err:5 http://in.archive.ubuntu.com/ubuntu bionic-updates InRelease
  Could not resolve 'in.archive.ubuntu.com'
Err:6 http://in.archive.ubuntu.com/ubuntu bionic-backports InRelease
  Could not resolve 'in.archive.ubuntu.com'
Reading package lists... Done
Building dependency tree       
Reading state information... Done
All packages are up to date.
W: Failed to fetch http://in.archive.ubuntu.com/ubuntu/dists/bionic/InRelease  Could not resolve 'in.archive.ubuntu.com'
W: Failed to fetch http://in.archive.ubuntu.com/ubuntu/dists/bionic-updates/InRelease  Could not resolve 'in.archive.ubuntu.com'
W: Failed to fetch http://in.archive.ubuntu.com/ubuntu/dists/bionic-backports/InRelease  Could not resolve 'in.archive.ubuntu.com'
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/bionic-security/InRelease  Could not resolve 'security.ubuntu.com'
W: Failed to fetch https://download.sublimetext.com/apt/stable/InRelease  Could not resolve 'download.sublimetext.com'
W: Failed to fetch http://dl.google.com/linux/chrome/deb/dists/stable/InRelease  Could not resolve 'dl.google.com'
W: Some index files failed to download. They have been ignored, or old ones used instead.
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
0

Como puede ver, el código de salida es 0 aunque encontramos un error. La razón de esto es que el programa o comando se ejecutó exitosamente. Sin embargo, no pudo actualizar las listas de paquetes para actualizaciones de paquetes que necesitan actualización.

La única explicación para esto es que el desarrollador del aptcomando no consideró el error al actualizar la lista de paquetes como un error para detener el comando y devolver un código de estado de salida de error. En cambio, el comando proporciona advertencias después de la ejecución.

Para comprender mejor voy a tomar un ejemplo de programa en C:

#include<stdio.h>

int main(int argc, char *argv[]) {
    if(argc==2) 
        printf("Welcome Master %s\n", argv[1]);
    else {
        fprintf(stderr, "Usage : %s <name>\n", argv[0]);
        return 1;
    }
    return 0;
}

Producción:

mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman
Usage : ./batman <name>
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
1
mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman Bruce
Welcome Master Bruce
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
0

Como puede ver, hay 2 códigos de estado de salida diferentes, porque como programador consideré que el comando ejecutado sin argumento es un error y debe terminar con el código de salida "1". (Podría elegir cualquier valor). Y si el comando se ejecutó correctamente, devolví "0" como código de estado de salida, lo que significa que no se encontró ningún error.

Tomemos otro ejemplo:

#include<stdio.h>

int main(int argc, char *argv[]) {
    if(argc==2) 
        printf("Welcome Master %s\n", argv[1]);
    else
        printf("ERROR!!\nUsage : %s <name>\n", argv[0]);

    return 0;
}

Producción:

mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman_error 
ERROR!!
Usage : ./batman_error <name>
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
0
mars@HP-Notebook:~/Desktop/Practice/cpp$ ./batman_error Bruce
Welcome Master Bruce
mars@HP-Notebook:~/Desktop/Practice/cpp$ echo $?
0

De nuevo el mismo programa, pero esta vez el programador (es decir, yo) no consideró finalizar el programa con un código de estado de salida diferente. Por lo tanto, aunque el terminal imprima una salida de Error, el código de estado de salida es "0".

Conclusión

Depende del desarrollador del programa qué valor devolver (es decir, código de estado de salida) dependiendo de la situación.
Espero que esto aclare el concepto de código de estado de salida.

Sugerencia sobre su script bash

Vi que estás usando un bucle que intentará ejecutar apt updateel comando 10 veces si no se ejecutó correctamente. Para ser honesto, si no funcionó la primera vez, tampoco funcionará las siguientes 9 veces. Por lo tanto, crear un bucle no tiene sentido.

Ahora, si desea comprobar si hay un error, utilice condiciones anidadas if-else. Puede verificar el código de estado en el primer nivel y verificar si hay errores con la ejecución en el aptsegundo nivel (es decir, con el código de salida "0") puede usar algo como:

sudo apt update | grep "Err"

Si greppude recuperar una línea, guárdela como un error en su archivo de registro; de lo contrario, la actualización se realizó correctamente.

Respuesta2

¿Por qué apt-get update devuelve 0? Sin embargo, quiero obtener otros números en lugar de 0 cuando falla el comando.

apt considera los errores transitorios de red como advertencias (no errores) que no causan un código de salida distinto de cero. Vereste código fuente.

Y para que mi script logre el propósito, ¿cómo podría modificarlo?

En el código fuente vinculado anteriormente, verá otra cláusula en el condicional ( errorMode != ErrorMode::Any). Para tratar las advertencias como errores, intente:

# apt -o 'APT::Update::Error-Mode=any' update

Esto hará que apt trate las advertencias como errores. Los errores de red transitorios harán que apt salga de un valor distinto de cero.

Puede agregar esto a apt conf si lo desea.

información relacionada